SpringIOC随笔(五)-Bean下

it2023-08-10  72

SpringIOC随笔(五)-Bean下

bean的生命周期

init-method

Bean创建后自动调用的方法

destroy-method

Bean销毁后自动调用的方法

public void myInit() { System.out.println("自定义init方法调用!"); } public void myDestroy() { System.out.println("自定义destroy方法调用!"); } <bean id="initDemo1" class="com.fxyh.bean.InitDemo1" init-method="myInit" destroy-method="myDestroy" />

bean创建后自动调用myInit方法,在销毁时自动调用myDestroy方法。

BeanNameAware接口的setBeanName方法

该方法是让bean获取自己在beanfactory中的名称。

@Override public void setBeanName(String name) { System.out.println("setBeanName:" + name + "调用!"); }

BeanFactoryAware接口的setBeanFactory方法

实现这个接口能通过这个方法获取当前的BeanFactory

@Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("setBeanFactory:" + beanFactory + "调用!"); }

ApplicationContextAware接口的setApplicationContext方法

实现这个接口可以得到当前bean的spring上下文

@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("setApplicationContext:" + applicationContext); }

InitializingBean接口的afterPropertiesSet方法

@Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet调用"); }

DisposableBean接口的destroy方法

@Override public void destroy() throws Exception { System.out.println("destory方法调用!"); }

BeanPostProcessor接口的两个方法(postProcessBeforeInitialization,postProcessAfterInitialization)

@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization: beanName=" + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization: beanName=" + beanName); return bean; }

这里有点意思的地方就是当这个bean实现了这个接口,那么这个bean就不会调用后置处理器了,也就是这两个方法,只有别的bean没有实现这个接口才会去调用别的实现了这个接口的bean的方法,而且没个bean都会调用一次这个方法,如果有多个bean实现了这个接口,那么这几个实现了后置处理器接口的bean的方法在bean初始化的时候,会调用每一个实现了这个接口的bean的这个方法。

而且实现了这个接口的bean一定会比没实现这个接口的bean早初始化。

当这个Bean配置为原型的时候,DisposableBean接口的destroy方法和自定义的destroy方法全部失效,不会调用。

结合之前的,当Bean配置为原型时,DisposableBean接口的destroy方法和自定义的destroy方法全部失效,然后lazy-init="false"也会失效。

代码

public class InitDemo1 implements Serializable, BeanNameAware, ApplicationContextAware, BeanFactoryAware, InitializingBean, DisposableBean { private static final long serialVersionUID = -2167328278489217537L; public InitDemo1() { System.out.println("InitDemo1构造方法调用!"); } public void myInit() { System.out.println("自定义init方法调用!"); } public void myDestroy() { System.out.println("自定义destroy方法调用!"); } public void service() { System.out.println("service方法调用!"); } @Override public void setBeanName(String name) { System.out.println("setBeanName:" + name + "调用!"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("setBeanFactory:" + beanFactory + "调用!"); } // @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization: beanName=" + beanName); return bean; } // @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization: beanName=" + beanName); return bean; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("setApplicationContext:" + applicationContext); } @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet调用"); } @Override public void destroy() throws Exception { System.out.println("destory方法调用!"); } } public class InitDemo2 implements Serializable,BeanPostProcessor{ private static final long serialVersionUID = 5867932081615656754L; public InitDemo2() { System.out.println("InitDemo2构造方法调用!"); } public void service() { System.out.println("InitDemo2service方法调用!"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization: beanName=" + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization: beanName=" + beanName); return bean; } } public class InitDemo3 implements Serializable, BeanPostProcessor { private static final long serialVersionUID = -3806397125776158318L; public InitDemo3() { System.out.println("InitDemo3构造方法调用!"); } public void service() { System.out.println("InitDemo2service方法调用!"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization: beanName=" + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization: beanName=" + beanName); return bean; } } applicationContext-init.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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="initDemo1" class="com.fxyh.bean.InitDemo1" init-method="myInit" destroy-method="myDestroy" scope="prototype"/> <bean id="initDemo2" class="com.fxyh.bean.InitDemo2" /> <bean id="initDemo3" class="com.fxyh.bean.InitDemo3"/> </beans> public class InitDemo1Test { private AbstractApplicationContext context; private InitDemo1 initDemo1; private InitDemo2 initDemo2; @Before public void setUp() throws Exception { this.context = new ClassPathXmlApplicationContext("classpath*:applicationContext-init.xml"); this.initDemo1 = this.context.getBean(InitDemo1.class); this.initDemo2 = this.context.getBean(InitDemo2.class); } @Test public void test(){ this.initDemo1.service(); this.initDemo2.service(); } @After public void after(){ this.context.close(); } }

使用注解的方式:

@PostConstruct

自定义init方法的注解

@PreDestroy

自定义destroy方法的注解

例子:

@Component public class InitDemoByAnnotation implements Serializable { private static final long serialVersionUID = -6995664151240989094L; public InitDemoByAnnotation() { System.out.println("InitDemoByAnnotation构造方法!"); } @PostConstruct public void myInit(){ System.out.println("自定义init方法!"); } @PostConstruct public void myInit2(){ System.out.println("自定义init2方法!"); } @PreDestroy public void myDestroy(){ System.out.println("自定义destroy方法!"); } @PreDestroy public void myDestroy2(){ System.out.println("自定义destroy2方法!"); } } <?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.fxyh.bean"/> </beans> public class InitDemoByAnnotationTest { private AbstractApplicationContext context; private InitDemoByAnnotation initDemoByAnnotation; @Before public void setUp() throws Exception { this.context = new ClassPathXmlApplicationContext("classpath*:applicationContext-annotation.xml"); this.initDemoByAnnotation = this.context.getBean(InitDemoByAnnotation.class); } @Test public void test(){ System.out.println(initDemoByAnnotation); } @After public void after(){ this.context.close(); } }

或者不使用xml,直接在test中把new ClassPathXmlApplicationContext();换成this.context = new AnnotationConfigApplicationContext("com.fxyh.bean");就好了。

这里自定义的init方法和destroy方法可以写多个,在XML中好像没办法写多个,可能是我不知道的原因吧,使用注解的时候写多个的时候,调用顺序是随机的,反正我在开发中也没有这样搞过。

最新回复(0)