SPRING-BOOT系列之Spring4深入分析
上篇 : SPRING-BOOT系列之Spring4快速入门
1. 假如我们有这样一个场景,在一个组件中想获取到容器对象,那么我们也可以使用Autowired来完成装配。那么我们还可以让类集成一个接口
// 如果我们不是要autowired生成 context的话,我们可以让类集成ApplicationContextAware接口让其生成 @Configuration public class TestAppAware implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void show(){ System.out.println("myContext is :" +applicationContext.getClass()); } }
public class App4 { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestAppAware.class); TestAppAware testAppAware = context.getBean(TestAppAware.class); testAppAware.show(); context.close(); } }
2. 我们再熟悉下,怎么在每个bean被容器init的时候可以做些什么处理?
我们写一个EchoBeanProcess 让其继承BeanPostProcessor,然后重写他的postProcessBeforeInitialization跟postProcessAfterInitialization方法,我们可以在容器init容器中的
bean的时候做一个处理:
@Component public class EchoBeanProcess implements BeanPostProcessor{ @Override public Object postProcessBeforeInitialization(Object bean, String beanName){ // 1. 要手动重写方法 // 2. 可以在return之前我们输入一些东西,相当于我们可以在这里对spring容器生成bean的时候做一个切面,前提 // !!!!!!!! 前提是你往当前容器中注入了 System.out.println("=========>init Before===》 :" +bean.getClass()); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName){ // 1. 要手动重写方法 // 2. 可以在return之前我们输入一些东西,相当于我们可以在这里对spring容器生成bean的时候做一个切面 System.out.println("=========>init After===》 :" +bean.getClass()); return bean; } }
public class App4 { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestAppAware.class,EchoBeanProcess.class); TestAppAware testAppAware = context.getBean(TestAppAware.class); testAppAware.show(); MyBean myBean = context.getBean(MyBean.class); System.out.println(myBean.getClass()); MyBean myBean2 = context.getBean(MyBean.class); System.out.println(myBean2.getClass()); context.close(); // 因为我们往容器当中注入了TestAppAware.class,所以我们能够看到Init 之前跟init之后的方法 } }
3. 从上面以及结合第一篇我们的Init跟destroy分析执行顺序,继承了BeanPostProcessor这个里面的2个方法是2个init方法,一个是init之前,一个是Init之后,而我们在生成bean
的时候是initMethod跟destoryMethod,所以顺序是 init之前 > initMethod > init之后 > detoryMethod.
4. 我们在利用刚才在 BeanPostProcessor 这个的时候写个代理,我们判断如果是DayService类,就返回他的子类DayServiceImpl ;
public class EchoBeanProcess implements BeanPostProcessor{ @Override public Object postProcessBeforeInitialization(Object bean, String beanName){ // 1. 要手动重写方法 // 2. 可以在return之前我们输入一些东西,相当于我们可以在这里对spring容器生成bean的时候做一个切面,前提 // !!!!!!!! 前提是你往当前容器中注入了; // 我们在这里做个代理处理 System.out.println("=========>init Before===》 :" +bean.getClass()); if(bean instanceof DayService) { return new DayServiceImpl(); } return bean; }
然后我们就可以在spring容器获取DayService对象的时候 我们就给个DaySerivceImpl返回出去。