spring深入-27-Spring启动constructor,@PostConstruct,afterPropertiesSet,onApplicationEvent顺序
(2017-05-11 14:21:29)分类: 框架 |
spring
启动时,按照constructor,@PostConstruct,afterPropertiesSet,onApplicationEvent执行顺序
ApplicationContext则是应用的容器。
Spring把Bean(object)放在容器中,需要用就通过get方法取出来。
ApplicationEven
是个抽象类,里面只有一个构造函数和一个长整型的timestamp。
ApplicationListener
是一个接口,里面只有一个onApplicationEvent方法。
所以自己的类在实现该接口的时候,要实装该方法。
如果在上下文中部署一个实现了ApplicationListener接口的bean,
那么每当在一个ApplicationEvent发布到 ApplicationContext时,
这个bean得到通知。其实这就是标准的Oberver设计模式。
@Autowired
private BeanFactory
beanFactory;
@Autowired
private
List<Builder> builders;
private
Map<States, Builder>
statesStateMachineMap = new
ConcurrentHashMap<>();
public BuildFactory()
{
System.out.println("constructor" + ":" +
builders);
}
@PostConstruct
public void
postConstructMethod() {
System.out.println("postConstruct" + ":" +
builders);
}
public void run(States
state, Events event) throws Exception{
Builder builder =
statesStateMachineMap.get(state);
StateMachine<States,
Events> stateMachine = builder.build(state,
beanFactory);
stateMachine.sendEvent(event);
}
public
StateMachine<States,
Events> create(States state) throws
Exception{
Builder builder =
statesStateMachineMap.get(state);
StateMachine<States,
Events> stateMachine = builder.build(state,
beanFactory);
stateMachine.getExtendedState().getVariables().put(InputObject.class,
new Student(1, "haha"));
return stateMachine;
}
@Override
public void
afterPropertiesSet() throws Exception {
statesStateMachineMap =
builders.stream().collect(Collectors.toMap(Builder::getName,
Function.identity()));
System.out.println("afterPropertiesSet" + ":" +
builders);
}
public void
testAop(String a) {
System.out.println(a + "testAop");
}
public void
test2Aop(String a) {
System.out.println(a + "testAop2");
}
public void
testAround(String a) {
System.out.println("run");
}
@MyAopAnno
public void
testAopAnno(Student student) {
System.out.println(student.getId() + "-" +
student.getName());
}
@Override
public void
onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent)
{
System.out.println("onApplicationEvent" + ":" +
builders);
}
注:什么是ApplicationContext?
它是Spring的核心,Context我们通常解释为上下文环境,但是理解成容器会更好些。 ApplicationContext则是应用的容器。
Spring把Bean(object)放在容器中,需要用就通过get方法取出来。
ApplicationEven
是个抽象类,里面只有一个构造函数和一个长整型的timestamp。
ApplicationListener
是一个接口,里面只有一个onApplicationEvent方法。
所以自己的类在实现该接口的时候,要实装该方法。
如果在上下文中部署一个实现了ApplicationListener接口的bean,
那么每当在一个ApplicationEvent发布到 ApplicationContext时,
这个bean得到通知。其实这就是标准的Oberver设计模式。
1.例如:
@Component
public class BuildFactory implements InitializingBean,
ApplicationListener<ContextRefreshedEvent>{
}
2. 结果:
constructor:null
postConstruct:[com.scn7th.newStateMachine.Builder1@219f4597,
com.scn7th.newStateMachine.Builder2@31be6b49]
afterPropertiesSet:[com.scn7th.newStateMachine.Builder1@219f4597,
com.scn7th.newStateMachine.Builder2@31be6b49]
onApplicationEvent:[com.scn7th.newStateMachine.Builder1@219f4597,
com.scn7th.newStateMachine.Builder2@31be6b49]
3.分析:
1)首先构造器被启动,此时还没有注入bean
2)postConstruct优先于afterPropertiesSet执行,这时bean属性竟然也被注入了
3)spring很多组建的初始化都放在afterPropertiesSet做。我们在做一些中间件想和spring一起启动,可以放在这里启动。Spring在设置完一个bean所有的合作者后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。
4)onApplicationEvent属于应用层的时间,最后被执行,很容易理解。onApplicationEvent会被频繁执行,需要使用它监听,需要考虑性能问题。很显然,这是观察者模式的经典应用。