为什么使用spring框架
1.解耦代码(每次使用都要new一个对象)
2.解决事务繁琐问题(创建对象----初始化----调用方法===销毁对象)
3.使用第三方框架麻烦的问题
总结:spring是一个轻量级的Ioc,Di和AOP容器
轻量级:简洁,高效,低依赖
**容器:**创建对象并将对象存储对象,同时管理着对象 的生命周期
理解IOC,DI,和spring什么关系
IOC"控制反转",DI"注入" 一个思想,将创建对象的操作给spring来做
spring 是这个思想之一
使用ioc和di功能
根据需求编写类
<!--只有DateSource对象才会配置初始化方法和销毁方法-->
<bean id="唯一性" class="类的全限定名" [innit-method="方法名" destroy-methoe="方法名"] >
<property name="属性名" value="属性值" |ref="容器中另外一个bean的id值"/>
......
</bean>
......
启动容器获取对象
手动启动容器
使用sprting测试启动容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“/01_hello.xml”)//需要在名字前面加/,
public class SpringTest {
@Autowired //对Di做解释,注入属性
//Person p1; 有多个对象的时候可以使用id的名字进行指定
Person person;
@Test//使用的spring中的test
public void test1(){
person.dowork();
System.out.println("执行spring单元测试");
}
Spring依赖版本
一般使用jdk8+5.x版本,不要随便更改spring的版本
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
Ioc思想
“控制反转”,将手动创建对象和对象之间的关系的控制权交给spring容器来控制
Di思想
“依赖注入”,使用setter方法和调用构造函数实现依赖注入
避免了从对象中繁琐的找依赖关系
bean三种注入方式:
setter,构造器注入,注解注入
**构造器注入的弊端:**若里面的属性形成循环依赖,使用构造器注入就不能成功创建对象并注入
**解决方法:**给一个类创设置一个setter方法,只有先创建一个对象之后才能创建其他对象
创建spring的xml配置文件
1.添加pom.xml中的spring依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
2.添加xml配置文件
<bean id="person" class="cn.wolfcode.Person"><!--Ioc创建对象并存储对象-->
<property name="name" value="灰灰"/><!--Di,使用setter方法和调用构造函数实现注入-->
</bean>
id:作为bean的名字
class:用于反射得到bean的实例
innit-method:初始化方法
destory-method:销毁方法
bean的作用域scope
在xml文件中进行配置
<bean id="" class="" scope="作用域"/>
单例:默认的是单例singleton:new的都是同一个对象,一般就是不写的
多例:设置scope为prototype,每次new的对象不相同
bean的初始化和销毁
spring在使用bean的时候立即自动初始化这个对象
spring可以在使用了bean之后自动使用close()方法将对象进行销毁
单例和多例在spring中销毁的区别:
单例:容器关闭的时候spring会自动进行销毁,因为单例存在spring容器中,容器就可以有权进行销毁
多例:容器关闭的时候不会被自动销毁,因为多例不在spring容器的管辖范围内,多例是被jvm的GC回收器进行处理,
bean:被容器管理的对象
在初始化容器的时候就已经将对象创建好了
从容器中获取bean方式
方式1使用Application获取bean
当多个对象由同一个实体类进行创建的时候,需要使用名字+类型进行获取bean
@Test
public void test3(){
ClassPathXmlApplicationContext ca = new ClassPathXmlApplicationContext("01_hello.xml");
//当有多个使用Person实体类创建对象时,使用按照名字和类型进行查找到具体的对象
Person person = ca.getBean("p1",Person.class);
System.out.println(person);
}
方式2,使用BeanFactory从容器获取对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = (MyBean) context.getBean("myBean"); // 通过名称获取
MyBean anotherBean = context.getBean("aliasOfMyBean", MyBean.class); // 通过别名获取
spring单元测试
执行顺序:jvm->junit->spring容器–>spring单元测试
spring中的单元测试会依赖于junit包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.8.RELEASE</version>
<scope>test</scope>
</dependency>
做测试需要贴的注解,启动容器
若不贴注解里面的值就是空的,会造成空指针异常
**作用:**减少了以前的做测试类的获取bean对象
启动容器:@RunWith(SpringJUnit4ClassRunner.class)
加载指定的配置文件:@ContextConfiguration(“xml配置文件”)
获取容器对象:@Autowired
测试方法:@Test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/01_hello.xml")//需要在名字前面加/,
public class SpringTest {
@Autowired //对Di做解释,注入属性
//Person p1; 有多个对象的时候可以使用id的名字进行指定
Person person;
@Test//使用的spring中的test
public void test1(){
person.dowork();
System.out.println("执行spring单元测试");
}
Di的注入
常量注入xml配置
可以使用的常量有:八大是基本类型,包装类,String,BigDecimal
使用里面的value属性进行常量注入
<property name="对象属性名称" value="需要注入的值"/>
<bean id="employee" class="cn.wolfcode.Employee">
<!--类型要和实体类中一一对应,底层可以对类型做转换-->
<property name="name" value="灰灰"/>
<property name="age" value="23"/>
<property name="salary" value="3200"/>
</bean>
注入bean,使用的频率很高
给对象注入的值时另一个对象,使用ref属性
<property name="对象属性名称" ref="容器另外一个 bean 的 id 值"/>
示例代码,dao层和service层
<!--使用实现类来创建对象,dao层-->
<bean id="EmployeeDAO" class="cn.wolfcode.EmployeeDAO"/>
<!--使用实现类进行创建对象,service层,service层需要使用dao层的对象,就需要使用bean注入-->
<bean id="employeeService" class="cn.wolfcode.EmployeeService">
<!--
name:使用反射到service层去找这个属性名,属性的类型要和ref所对应的属性相同
ref:容器中另一个bean的id值
-->
<property name="EmployeeDAO" ref="EmployeeDAO"/>
</bean>
使用contex标签添加配置数据库的配置文件,此时需要添加该标签的依赖
xmlns:context="http://www.springframework.org/schema/context"
<context:property-placeholder location="/db.properties"/>
spring使用${}进行引用,配置文件中的key的名字需要不同
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<!--使用不同的用户名进行读取,保证不读到最大的那个用户名-->
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
总结
1.以后所有创建对象的操作全部交给spring的xml文件来做
2.使用bean注入的时候使用时property标签中的ref属性
3.spring创建对象的时候使用的实现类进行创建
4.创建对象的时候需要在类里面设置setter方法,spring才能使用反射进行属性的获取,并给这个对象赋值
5.连接数据库的时候需要添加配置文件,给配置文件中的key设置名字,防止spring读取的时候读到最大的权限
### 总结
**1.以后所有创建对象的操作全部交给spring的xml文件来做**
**2.使用bean注入的时候使用时property标签中的ref属性**
**3.spring创建对象的时候使用的实现类进行创建**
**4.创建对象的时候需要在类里面设置setter方法,spring才能使用反射进行属性的获取,并给这个对象赋值**
5.连接数据库的时候需要添加配置文件,给配置文件中的key设置名字,防止spring读取的时候读到最大的权限