三天学会Spring?第二天!!!!
spring学习第二天
①depends-on属性,设置依赖
容器中对象创建的顺序跟applicationContext.xml文件配置的顺序有关
如下代码:创建三个类顺序是ACB三个类
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="a" class="com.student.pojo.A"></bean>
<bean id="c" class="com.student.pojo.C"></bean>
<bean id="b" class="com.student.pojo.B"></bean>
</beans>
类C的代码
package com.student.pojo;
public class C {
public C() {
System.out.println("C 被创建");
}
}
类B的代码
package com.student.pojo;
public class B {
public B() {
System.out.println("B 被创建");
}
}
类A的代码
package com.student.pojo;
public class A {
public A() {
System.out.println("A 被创建");
}
}
输出的结果
A 被创建
C 被创建
B 被创建
依赖注入如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="a" class="com.student.pojo.A" depends-on="b"></bean>
<bean id="c" class="com.student.pojo.C" depends-on="a"></bean>
<bean id="b" class="com.student.pojo.B"></bean>
</beans>
关键字depends-on=“唯一标识”:代表着该类要创建对象,必须依赖哪个类,依赖的类的对象必须先创建出来,我自己才能创建
输出结果:
B 被创建
A 被创建
C 被创建
②基于XML文件配置的自动注入:
请看下面的两个实体类People类和Car类
package com.student.pojo;
public class People {
private String name;
private Car car;
public People(String name, Car car) {
super();
this.name = name;
this.car = car;
}
public People() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
@Override
public String toString() {
return "People [name=" + name + ", car=" + car + "]";
}
}
package com.student.pojo;
public class Car {
private String carNum;
private String carName;
public Car() {
super();
}
public Car(String carNum, String carName) {
super();
this.carNum = carNum;
this.carName = carName;
}
public String getCarNum() {
return carNum;
}
public void setCarNum(String carNum) {
this.carNum = carNum;
}
public String getCarName() {
return carName;
}
public void setCarName(String carName) {
this.carName = carName;
}
@Override
public String toString() {
return "Car [carNum=" + carNum + ", carName=" + carName + "]";
}
}
在applicationContext.xml文件中的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="car" class="com.student.pojo.Car">
<property name="carNum" value="皖P888888"></property>
<property name="carName" value="老死nice"></property>
</bean>
<bean id="peo" class="com.student.pojo.People">
<property name="name" value="张三"></property>
</bean>
</beans>
如图我并没有将Car与people的car完成绑定在一起,我只设置了People的name 属性,并没有设置车的属性,当然输出结果不会完成绑定!
People [name=张三, car=null]
但是我们将xml文件进行添加如下图所示:
<bean id="peo" class="com.student.pojo.People" autowire="byName">
<property name="name" value="张三"></property>
</bean>
People [name=张三, car=Car [carNum=皖P888888, carName=老死nice]]
我们增加了一个属性autowire="byName"
byName属性是:通过实体类的属性名:如下
private Car car;
通过这个实体类属性名car去找xml文件配置的id的名字为car,如果找到了则自动的注入!同理如果xml文件不是car也不会完成注入
byType属性是根据类型进行注入,显然如果我们配置多个car的对象都会注入,但是肯定会报错,因为自动注入是不知道该注入哪一个的!!!!
constructor属性根据有参数的构造方法,先按照类型进行注入,如果查找到多个根据名字在进行查找。
③IOC之bean单例和多例
scpoe类型
singleton表示单例的,对象在applicationContext.xml文件被加载,spring容器被创建的时候被创建。(不设置scope属性,默认是单例的)
实体类中不重写toString方法(便于看的清晰)每次调用getBean得到的是唯一的对象
<bean id="p10" class="com.student.pojo.People" scope="singleton">
<property name="id" value="1"></property>
</bean>
protopyte值,在spring容器创建的时候不会创建对象,每一次调用getBean是创建一个新的对象
在web环境下还有另外两个值。request 和session
request表示,在一次请求中(一次request中)多次调用getBean方法,只返回唯一一个对象
底层实现原理大概是这样
//先获取看你有没有,没有就创建一个,有就直接返回bean
Object bean=request.getAttribute("唯一标识id");
if(bean==null){
bean=new 对象();
request.setAttribute("唯一标识id",bean);
}
return bean;
session值,表示在一次会话中,多次调用getBean方法返回唯一一个对象。
底层实现原理同上面一样
Object bean=request.getSession().getAttribute("唯一标识id");
if(bean==null){
bean=new 对象();
request.getSession().setAttribute("唯一标识id",bean);
}
return bean;
Bean对象的生命周期
①IOC之bean的生命周期
先写一个实体类,在里面写上初始化方法和销毁的方法。init和destroy(方法名可以自己定义!)
package com.student.pojo;
public class Teacher {
private String name;
private int age;
public void init() {
System.out.println("对象被初始化");
}
public void destroy() {
System.out.println("对象被销毁");
}
public Teacher() {
super();
System.out.println("对象被创建!");
}
public Teacher(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Teacher [name=" + name + ", age=" + age + "]";
}
}
XML文件的配置
<bean id="t10" class="com.student.pojo.Teacher" init-method="init" destroy-method="destroy">
<property name="name" value="Lisa"></property>
<property name="age" value="20"></property>
</bean>
Test类:
package com.student.Test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class peoTest {
@Test
public void test1() throws Exception {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
结果:
对象被创建!
对象被初始化
当spring 容器关闭的时候,调用销毁的方法。
特别注意:该种情况使用于单例(单例是在spring容器创建的时候会创建对象,然后调用初始化的方法。)对于多例(spring容器被创建的时候并不会创建对象,当然也就不会进行初始化的操作,当我们调用getBean方法时,才会创建对象,才会进一步进行初始化的方法,多例不会调用销毁方法。)
②后置处理器BeanPostProcessor
使用步骤:
1.创建一个类实现BeanPostProcessor接口,实现方法(2个)
2…spring容器中进行配置。
package com.student.until;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanProce implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String id) throws BeansException {
System.out.println("初始化之后调用");
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String id) throws BeansException {
System.out.println("初始化之前调用");
return bean;
}
}
XML文件的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="t10" class="com.student.pojo.Teacher" init-method="init" destroy-method="destroy">
<property name="name" value="Lisa"></property>
<property name="age" value="20"></property>
</bean>
<bean class="com.student.until.MyBeanProce"></bean>
</beans>
输出结果:
对象被创建!
初始化之前调用
对象被初始化
初始化之后调用
在完后初始化的前后进行一些操作比如:
spring 管理数据库连接池(重点)
①spring配置管理数据库连接池对象
第一步导入jar,在四个基本包和1个日志包的基础上增加一个数据库连接的jar和一个阿里的数据库连接池的包
在applicationContext.xml文件配置中书写:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="root"></property>
<property name="password" value="2020"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/express"></property>
<property name="initialSize" value="5"></property>
<property name="maxActive" value="10"></property>
</bean>
测试类
package com.student.test;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class DataSourceTest {
@Test
public void test1() throws Exception {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource=(DataSource)ac.getBean("dataSource");
System.out.println(dataSource.getConnection());
}
}
②spring引入单独的jdba.properties配置文件
一:在SRC下新建一个文件取名为jdbc.properties
二:在applixationContext.xml文件中配置
spring中的PropertyPlaceholderConfigurer类
③使用context名称空间加载配置属性
添加命名空间context:
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
</beans>
如果记不住那个类太长了,那么我们可以使用这种办法。比较好记简单
注解配置bean对象
①注解配置Dao,Service,Controller组件
@Controller 配置控制器(框架中的Servlet)
@Service service业务层组件
@Repository 持久层DAO
@Component 除了以上三种都可以用Component
@Scope 配置作用域(单例多例)
1.导入jar包,在五个包的基础上导入AOP的包,注解
2.在applicationContext.xml文件中配置如下:扫描包中的注解
<context:component-scan base-package="c0m.student"/>
通过注解配置的默认的
<bean id=“abc” calss=“com.student.xxx.Abc”>
也可以自定义名称id
例如:
@Controller(“ban”)
@Service (“doService”)
②自定义包扫描排除设定
③常使用的一些注解
在开发过程中,我们会在Service层调用DAO层对数据库进行操作通常将DAO层私有化,如下:然后在Service里面调用
例如:bookDao.add(new book)
bookDao.changeName(“name”);
这样 @Autowired能给我们的开发提高简便。
@Qualifier
配置下面的注解,相当于告诉spring,你找到这个bookDao那就用这个吧,我这里的是bookDao1,咱们是一样的, bookDao1是我这给你起的外号。。。
④spring扩展junit测试
我们在测试的时候一般多次写获取spring容器取出自己需要的对象,这样很麻烦。如下:
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Object o=ac.getBean("唯一标识");
现在我们只需要导包 spring-text
编写两个注解