ApplicationContextAware接口
ApplicationContextAware
是用来获取spring的上下文。通过工具类直接实现该接口,返回ApplicationContext
对象。
- 实现类
@Component
public class SpringContextUtil implements ApplicationContextAware{
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
//获取Spring容器context
this.applicationContext=arg0;
}
public static ApplicationContext getSpringContext(){
return applicationContext;
}
}
- Junit测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:config/spring-mvc.xml","classpath*:config/spring-common.xml"})
public class UserControllerTest {
/**
* Spring应用上下文
*/
@Autowired
private ApplicationContext context;
@Test
public void test() {
System.err.println(context);
ApplicationContext springContext = SpringContextUtil.getSpringContext();
System.err.println(springContext);
}
}
- 测试结果:
可以看到,打印了两次ApplicationContext
的结果,其中一次是通过@Autowired
注入的,另外一个就是实现ApplicationContextAware
接口时获取的。项目中可以通过这两种之一来获取上下文对象。
ApplicationEvent和ApplicationListener
ApplicationEvent
对应定义事件,ApplicationListener
定义监听事件。一般用来处理一些异步的操作。比如一些异步入库等。
- 定义自定义事件
MySpringEvent
public class MySpringEvent extends ApplicationEvent {
private String name;
/**
* 异步调用很方便。比如说
*/
public MySpringEvent(Object source, String name) {
super(source);
this.name = name;
}
@Override
public Object getSource() {
return super.getSource();
}
@Override
public String toString() {
return super.toString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 定义事件监听器
@Component
public class MyApplicationListener implements ApplicationListener<MySpringEvent>{
public void onApplicationEvent(MySpringEvent event) {
if(event instanceof MySpringEvent){
//执行一些自定义操作,这里打印一下。
MySpringEvent mySpringEvent=(MySpringEvent)event;
System.out.println("-------------------- "+mySpringEvent.getName()+"---------------");
}
}
}
- 测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:config/spring-mvc.xml","classpath*:config/spring-common.xml"})
public class MyApplicationListenerTest {
@Autowired
public ApplicationContext applicationContext;
@Test
public void test() {
applicationContext.publishEvent(new MySpringEvent("source", "Tom"));
}
}
一般在业务中发布一个事件。比如说异步入库。那自定义事件应该就是一个对象,监听器就是应该入库的操作,在其他业务要触发的时候在发布事件。
InitializingBean
InitializingBean接口为bean提供了初始化方法的方式。但是会在使用配置init-method前面执行。
- 实现接口
InitializingBean
@Component
public class InitializingBeanBean implements InitializingBean{
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean初始化Bean,init-method在后面执行。");
}
}
- 测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:config/spring-mvc.xml","classpath*:config/spring-common.xml"})
public class InitTest {
@Test
public void test() {
System.out.println("启动完毕");
}
}
使用init-method
来初始化bean
spring配置:
<bean id="init" class="com.tgb.inter_face.InitMethodBean" init-method="execute"></bean>
对应类:
public class InitMethodBean {
public void execute(){
System.out.println("我是通过init-method调用的");
}
}
结果都是可以打印出来。
DisposableBean
bean在销毁的时候调用的
@Component
public class InitializingBeanBean implements InitializingBean,DisposableBean{
/**
* bean在初始化的时候调用
*/
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean初始化Bean,init-method在后面执行。");
}
/**
* bean在销毁的时候调用的
* @throws Exception
*/
public void destroy() throws Exception {
System.out.println("bean在销毁的时候调用的");
}
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath*:config/spring-mvc.xml","classpath*:config/spring-common.xml"})
public class InitTest {
@Autowired
ApplicationContext applicationContext;
@Test
public void test() {
System.out.println("启动完毕");
//tomcat里面要手动,关闭上下文,会调用到destroy
ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
context.close();
}
}
FactoryBean
使用场景:1、通过外部对类是否是单例进行控制,该类自己无法感知 2、对类的创建之前进行初始化的操作,在afterPropertiesSet()中完成。
- 继承该接口后实现的三个方法。
/**
* 工厂Bean,返回的是该工厂Bean的getObject方法所返回的对象。创建出来的对象是否属于单例由isSingleton中的返回决定。
*/
public User getObject() throws Exception {
return new User();
}
public Class<?> getObjectType() {
return User.class;
}
public boolean isSingleton() {
return true;
}
获取bean,使用上下文获取bean
User bean = context.getBean(User.class);
BeanPostProcessor
每个bean初始化前后都会调用一次。
/**
*
* @param arg0
* @param arg1
* @return
* @throws BeansException
*/
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("bean初始化前调用"+arg1);
return arg0;
}
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out.println("bean初始化后调用"+arg1);
return arg0;
}
BeanFactoryPostProcessor
BeanFactory的后置处理器。需要在Bean的配置文件中,注册BeanFactory的后置处理器。
public class BeanFactory implements BeanFactoryPostProcessor{
public BeanFactory() {
System.out.println("初始化BeanFactory");
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out.println("hello,我是BeanFactoryPostProcessor");
}
}
spring.xml
<bean id="beanFactory" class="com.tgb.inter_face.BeanFactory"></bean>
总结
- 实现BeanFactoryPostProcessor接口,初始化BeanFactory时候会调用。
- 实现InitializingBean接口,bean在初始化的时候调用afterPropertiesSet();
- 实现BeanPostProcessor,可以在每个bean前后调用一次。
- 使用init-method初始化的方法执行。
- 实现FactoryBean工厂接口自定义的bean初始化。
- 实现DisposableBean接口,销毁bean时调用。