* Bean的生命周期
* init-method:初始化的时候执行的方法:
*destroy-method:销毁的时候执行的方法:
* Bean生成必须是单例的.在工厂关闭的时候销毁.
但是关闭必须手动执行手动销毁的方法.也就是applicationContext.closed()
1.instantiate bean对象实例化(初始化)
2.populate properties 封装属性(属性的注入)
3.如果Bean实现BeanNameAware 执行 setBeanName(配置Spring中的id或者name)
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization(执行初始化之前执行的方法)(AOP底层)
6.如果Bean实现InitializingBean 执行 afterPropertiesSet (属性注入完成)
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization(执行初始化之后执行的方法)(AOP底层)
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
* 第三步和第四步:让JavaBean了解Spring的容器.
***** 第五步和第八步非常重要:
BeanPostPorcessor:在Bena的实例化的过程中对Bean进行增强. (需要自己配置,配置不需要配ID,也叫后处理Bean,Spring 底层会自动调)
* Factory hook that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
* 增强一个Bean中某个方法需要几种方式:
* 继承:
* 能够控制这类的构造!!!,这个类你可以自己去new它或者你自己能提供这个类
* 装饰者模式:
* 被增强类和增强类实现相同的接口.
* 在增强的类中获得到被增强类的引用.
***** 缺点:接口中方法太多.其他都需要原封调用.
* 动态代理:(灵活)
* JDK动态代码:类实现接口.
* 对实现接口的类产生代理.
测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package
com.mickeymouse.spring.demo4;
import
org.springframework.beans.BeansException;
import
org.springframework.beans.factory.BeanNameAware;
import
org.springframework.beans.factory.DisposableBean;
import
org.springframework.beans.factory.InitializingBean;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.ApplicationContextAware;
/**
* Bean的完整的生命周期的十一个步骤:
*/
public
class
ProductDaoImpl
implements
ProductDao,BeanNameAware ,ApplicationContextAware,InitializingBean,DisposableBean {
private
String name;
public
ProductDaoImpl() {
super
();
System.out.println(
"第一步:实例化Bean"
);
}
public
void
setName(String name) {
System.out.println(
"第二步:属性注入:"
+name);
this
.name = name;
}
@Override
public
void
setBeanName(String beanName) {
System.out.println(
"第三步:获得Bean的名称"
+beanName);
}
@Override
public
void
setApplicationContext(ApplicationContext applicationContext)
throws
BeansException {
System.out.println(
"第四步:让Bean了解Spring的工厂..."
);
}
@Override
public
void
afterPropertiesSet()
throws
Exception {
System.out.println(
"第六步:属性设置完成..."
);
}
public
void
setup(){
System.out.println(
"第七步:执行手动配置的初始化方法..."
);
}
public
void
save(){
System.out.println(
"第九步:执行业务save方法..."
);
}
public
void
update(){
System.out.println(
"第九步:执行业务update方法..."
);
}
@Override
public
void
destroy()
throws
Exception {
System.out.println(
"第十步:执行Spring中提供的对象销毁的方法..."
);
}
public
void
teardown(){
System.out.println(
"第十一步:执行手动配置的销毁的方法"
);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
package
com.mickeymouse.spring.demo4;
import
java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method;
import
java.lang.reflect.Proxy;
import
org.springframework.beans.BeansException;
import
org.springframework.beans.factory.config.BeanPostProcessor;
public
class
MyBeanPostProcessor
implements
BeanPostProcessor {
@Override
public
Object postProcessBeforeInitialization(Object bean, String beanName)
throws
BeansException {
System.out.println(
"第五步:执行初始化前执行的方法..."
);
return
bean;
}
@Override
public
Object postProcessAfterInitialization(
final
Object bean, String beanName)
throws
BeansException {
System.out.println(
"第八步:执行初始化后执行的方法..."
);
// 使用动态代理:
if
(beanName.endsWith(
"Dao"
)){
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(),
new
InvocationHandler() {
@Override
public
Object invoke(Object proxy, Method method, Object[] args)
throws
Throwable {
if
(
"save"
.equals(method.getName())){
System.out.println(
"===============权限校验"
);
return
method.invoke(bean, args);
}
return
method.invoke(bean, args);
}
});
return
proxy;
}
return
bean;
}
}
|
1
2
3
4
5
|
package
com.mickeymouse.spring.demo4;
public
interface
ProductDao {
public
void
save();
public
void
update();
}
|
XML配置
1
2
3
4
5
|
<
bean
id
=
"productDao"
class
=
"com.itheima.spring.demo4.ProductDaoImpl"
init-method
=
"setup"
destroy-method
=
"teardown"
>
<
property
name
=
"name"
value
=
"空调"
/>
</
bean
>
<
bean
class
=
"com.itheima.spring.demo4.MyBeanPostProcessor"
/>
|
TestDemo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package
com.mickeymouse.spring.demo4;
import
org.junit.Test;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Bean的完整生命周期的测试
* @author mickeymouse
*
*/
public
class
SpringDemo4 {
@Test
public
void
demo1(){
ClassPathXmlApplicationContext applicationContext =
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
ProductDao productDao = (ProductDao) applicationContext
.getBean(
"productDao"
);
productDao.save();
productDao.update();
applicationContext.close();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package
com.mickeymouse.context;
import
java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method;
import
java.lang.reflect.Proxy;
import
org.springframework.beans.BeansException;
import
org.springframework.beans.factory.config.BeanPostProcessor;
public
class
MyBeanPostProcessor
implements
BeanPostProcessor {
/**
* 目的:增强我们一个对象的某个方法,让执行这个方法的时候有个权限校验
* eg:增强XXXDao这个类中的save方法
*/
public
Object postProcessAfterInitialization(
final
Object bean, String beanname)
throws
BeansException {
//判断假如我们的对象名是以Dao结尾的,那么我们就进行增增强处理
if
(beanname.endsWith(
"Dao"
)) {
//生成代理对象
Object proxy = Proxy.newProxyInstance(MyBeanPostProcessor.
class
.getClassLoader(), bean.getClass().getInterfaces(),
new
InvocationHandler() {
//代理对象里的方法
public
Object invoke(Object proxy, Method method, Object[] args)
throws
Throwable {
//如果是代理执行的是save方法
if
(
"save"
.equals(method.getName())) {
System.out.println(
"我执行了权限校验"
);
return
method.invoke(bean, args);
}
return
method.invoke(bean, args);
}
});
return
proxy;
}
//如果不是以Dao结尾额,我们不用管,原封不动的返回
return
bean;
}
public
Object postProcessBeforeInitialization(Object bean, String beanname)
throws
BeansException {
// TODO Auto-generated method stub
return
bean;
}
}
|