一. spring概述
1. spring是什么
spring:是一个轻量级的,IOC和AOP的一站式java开发框架,为简化企业级应用开发而生的
spring官方网站
2. 轻量级
轻量级:spring框架使用的核心jar包都比较小,运行占用资源小,开发效率高
3. IOC
IOC(Inversion of Control):反转控制,是一种编程思想,将对象的管理交给spring框架,不用我们自己创建对象
4. AOP
AOP(Aspect Oriented Programming):面相切面编程,是一种编程思想,可以为我们的程序动态的添加某种功能,而不用修改原本的代码
5. 一站式框架
一站式框架:在IOC和AOP的基础上spring还对数据访问层和web层进行了封装
6. spring体系结构图
二. spring搭建
1. Maven导入spring核心jar
<!--spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
2. 创建一个实体类
package com.ffyc.springpro.model;
public class Admin {
private String account;
private String password;
private Integer id;
public Admin() {
System.out.println("Admin无参构造方法");
}
public Admin(String account, String password, Integer id) {
this.account = account;
this.password = password;
this.id = id;
}
public Admin(String account, String password) {
this.account = account;
this.password = password;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Admin{" +
"account='" + account + '\'' +
", password='" + password + '\'' +
", id=" + id +
'}';
}
}
3. 编写spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--可以通过bean标签让spring管理我们某个类生成的对象-->
<bean id="给类起别名" class="全类名"></bean>
</beans>
4. 测试spring
public class Test2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Admin admin1 = applicationContext.getBean("admin", Admin.class);
Admin admin2 = applicationContext.getBean("admin", Admin.class);
System.out.println(admin1);
System.out.println(admin2);
}
}
使用spring中的ClassPathXmlApplicationContext类读取spring配置文件,然后调用里面的getBean方法即可获取到spring帮我们创建的对象
三. IOC
IOC(Inversion of Control):反转控制,是一种编程思想,将对象的管理交给spring框架,不用我们自己创建对象
那么spring是如何对对象进行管理的?
1. spring Bean管理
Bean:由spring创建的对象就叫做Bean.
注意:spring创建的对象和普通new出来的对象有区别,普通new出来的对象是最原生的,里面没有任何功能,而spring创建出来的对象中往往会附带一些其他功能
spring管理Bean对象的方式有两种,分别是XML的方式和注解的方式
1.1 基于XML方式管理Bean
1.1.1 创建Bean
通过<bean></bean>标签配置需要让spring管理的类
<bean id="admin" name="admin1,admin2" class="com.ffyc.springpro.model.Admin" scope="prototype">
</bean>
<bean></bean>标签中常用的属性
id: 生成的对象名,每个bean对象的id必须是唯一的
name: 给bean对象起别名,一个bean对象的别名可以为多个
class:bean对象所在类的全类名,以便spring根据反射机制创建出该类的对象
scope:
scope是指定spring创建对象的方式
1. singleton(默认的):单例模式,spring默认只会创建一个该类的对象,无论你调用几次getBean()方法,返回的对象都是同一个
public class Test2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Admin admin1 = applicationContext.getBean("admin", Admin.class);
Admin admin2 = applicationContext.getBean("admin", Admin.class);
System.out.println(admin1);
System.out.println(admin2);
}
}
这里可以看到构造方法只被执行一次,且输出的两个对象地址相同
2. prototype:原型模式,调用一次getBean()方法就会创建一次该类的对象
同样的代码只修改bean标签的scope属性结果不同,prototype可以创建多个对象
3. request:每次http请求就会创建一个bean对象,仅用于WebApplicationContext环境
1.1.2 依赖注入
通过<bean></bean>标签可以实现让spring来管理该类的对象,那么spring如何在创建对象的同时就给对象赋值呢,这就要通过spring的依赖注入
依赖注入(DI:Dependency Injection):指spring在创建对象的同时将对象所依赖的属性通过配置设置给对象
简单来说就是spring在创建对象的同时给对象赋初值
注入的方式分为set注入和构造方法注入
1. set注入
set注入:spring在创建对象的同时通过set方法注入
<bean id="admin" name="admin1,admin2" class="com.ffyc.springpro.model.Admin" scope="prototype">
<!--
方式一:通过set方法注入
-->
<property name="id" value="100"></property>
<property name="account" value="admin"></property>
<property name="password" value="111"></property>
</bean>
set注入就是通过<property name="类中的属性名" value="要赋的值"></property>标签来给对象初始化的
注意: name后面跟的是类中的属性名,value后面是要赋的值
2. 构造方法注入
构造方法注入:spring在创建对象的同时通过构造方法注入
<bean id="admin" name="admin1,admin2" class="com.ffyc.springpro.model.Admin" scope="prototype">
<!--
方式二:通过构造方法注入
-->
<constructor-arg name="id" value="101"></constructor-arg>
<constructor-arg name="account" value="admin"></constructor-arg>
<constructor-arg name="password" value="111"></constructor-arg>
</bean>
构造方法注入就是通过<constructor-arg></constructor-arg>标签来调用具体的构造方法实现给对象注入值的,同样name后面是类中的属性,value后面是要赋的值
注意:
<constructor-arg></constructor-arg>标签有几组,就要定义对应的参数的构造方法,比如上述案例中就要定义含有三个参数的构造方法
1.2 注解方式管理Bean
用注解方式管理Bean之前首先要在spring的配置文件中进行配置
<!--开启注解扫描-->
<context:component-scan base-package="包名"> </context:component-scan>
开启注解扫描,会对指定包名下的所有类进行扫描,检查有spring注解标签的类,加了标签的类就会被spring进行管理,没加就不管,这样就不用一个一个在xml中进行配置
1.2.1 创建Bean
用注解的方式创建Bean,想让spring管理哪个类,只需要在该类上加一个注解标签即可,但由于spring分类比较细,所以在不同包(层)中加的注解标签不同,但作用都是让spring管理该类的对象
1.@Component:用在model包(层)上的类,加了该标签就表示spring管理了该类
2.@Service:用在service包(层)上的类,加了该标签就表示spring管理了该类
3.@Repository:用在dao包(层)上的类,加了该标签就表示spring管理了该类
这三个注解标签都有value属性,作用就和xml文件中的<bean></bean>标签中的id属性一样,用于作为该类的唯一标识
eg:@Component(value=“user”)等同于<bean id="user" class="...."></bean>
注意:以上标签都可以用于创建对象,只是为了后续扩展功能,在不同层使用不同的标签
@Scope(value=“prototype”) 原型
@Scope(value=“ singleton ”) 单例
这两个标签等同于<bean></bean>标签中的scope属性
1.2.2 依赖注入
1. 使用spring提供的注解标签注入
@Autowired是spring提供的注解,可以写在字段(类中的属性)和setter方法上,如果写在字段上就不需要getter和setter方法,默认情况下它要求注入依赖的对象必须存在,而且必须也是由spring管理,如果允许null值,可以设置required属性为false
1.1 通过名称找bean并注入
如果要通过名称找bean对象,那么还需要和@Qualifier注解一起使用,设置@Qualifier标签的value属性,同时这个类上的创建对象的标签后面也要指定value属性,两者值相同,就相当于<bean>标签中的id属性
这样在通过@Autowired标签来进行依赖注入时就知道要找名字为哪个类的对象了
1.2 通过类型找bean并注入
通过类型找bean的方式更为简单,只需要在要注入的成员属性上加@Autowired注解标签即可,spring在注入时,会根据成员属性的类型去找对应的类,因为前面使用注解时已经配置过包名了,一个包下的类一定是确定的,不能有同名类,所以也可以通过类型找bean对象注入
2. 使用jdk提供的标签注入
1.1 通过名字查找bean并注入
在要注入的属性上使用@Resource标签,并设置name属性为某个类中标签的value属性即可通过名字查找,不像spring中@Autowired标签那样还要配合@Qualifier标签一起使用
1.2 通过类型查找bean并注入
直接在要注入的属性上使用@Resource标签即可
1.3 xml和注解的对比
注解优点:方便,直观,高效(代码少,没有配置文件的书写那么复杂)
注解缺点:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的(maven重新编译).
xml优点:配置和代码是分离的,在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载.
xml缺点:编写麻烦,效率低,大型项目过于复杂.
四. Spring数据访问层管理
以前连接数据库的对象都是我们自己创建的,自己管理的,那么有了spring之后,我们可以将连接数据库的对象(数据源)交给spring帮我们管理,我们只需要在使用的地方注入即可
1. Maven导入所需要的jar
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- 阿里数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
2. 让spring管理数据库连接对象
<!--
让spring管理阿里巴巴数据库连接对象
-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverClassName}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${uname}"></property>
<property name="password" value="${pwd}"></property>
<property name="initialSize" value="${initialSize}"></property>
<property name="maxActive" value="${maxActive}"></property>
</bean>
这里为了防止以后项目多不便于修改所以将value的值提取到一个配置文件中(config.properties)用键值对存储,使用时只需要将配置文件导入spring的配置文件中,并且用${}的方式获取键对应的值,这样做的好处,就是为了便于以后修改,只需要找到配置文件修改值即可
配置文件如下:
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai
uname=root
pwd=root
initialSize=5
maxActive=20
在spring的配置文件中导入该文件
<!--导入属性文件-->
<context:property-placeholder location="config.properties"/>
3. 创建一个spring封装JDBC的类
<!--
创建spring对jdbc进行封装的一个JdbcTemplate类,Jdbctemplate中提供了许多访问数据库的方法
-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
注意:这个spring封装的JDBC我们只在这里当做案例,因为已经学过Mybatis,下面会直接集成Mybatis
4. 测试
@Service(value = "adminServlet")
public class AdminServlet {
@Resource
AdminDao adminDao;
public void saveAdmin(){
adminDao.save();
}
public AdminDao getAdminDao() {
return adminDao;
}
public void setAdminDao(AdminDao adminDao) {
this.adminDao = adminDao;
}
}
@Repository(value = "adminDao")
public class AdminDao {
@Autowired
JdbcTemplate jdbcTemplate;
public void save(){
System.out.println("保存管理员");
jdbcTemplate.execute("insert into admin(account,password)values('小明','66666')");
}
}
五. spring集成Mybatis
首先先配置好一个普通的mybatis项目,然后再添加spring项目
这里mybatis配置文件需要删除数据库连接池部分和导入Mapper文件部分,可以只保留如下部分
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <!--.dtd文件是用来规定标签语法规范的-->
<configuration>
<settings>
<!--打印执行日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启数据库列名 与 java属性名之间的转换 user_name userName-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--为类型配置别名-->
<typeAliases>
<package name="com.ffyc.ssm.model"/>
<!--<typeAlias type="com.ffyc.mybatis.model.Admin" alias="admin"></typeAlias>-->
</typeAliases>
</configuration>
1.导入spring结合mybatis 等jar包
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<!--spring-context-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- 阿里数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--spring结合mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
2. 配置spring配置文件
2.1 spring管理druid数据源
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driverClassName}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${uname}"></property>
<property name="password" value="${pwd}"></property>
<property name="initialSize" value="${initialSize}"></property>
<property name="maxActive" value="${maxActive}"></property>
</bean>
2.2 spring管理sqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis.xml"></property>
<property name="mapperLocations" value="classpath:mappers/*Mapper.xml"></property>
</bean>
注意这里是将duri对象当做mybatis中sqlSessionFactory的数据源,也就是将mybatis中数据库连接对象和数据库连接池部分换成duri,提高性能
2.3 指定生成接口代理
<bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ffyc.ssm.dao"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
2.4 测试
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Admin admin = applicationContext.getBean("admin",Admin.class);
admin.setAccount("admin");
admin.setPassword("111");
LoginService loginService = applicationContext.getBean("loginService",LoginService.class);
System.out.println(loginService.Login(admin));
}
}
@Repository
public interface LoginDao {
@Select("select * from admin where account=#{account} and password=#{password}")
Admin login(Admin admin);
}
@Service
public class LoginService {
@Autowired
LoginDao loginDao;
public Admin Login(Admin admin){
Admin admin1 = loginDao.login(admin);
return admin1;
}
}
查询成功