Spring 源码梳理(六) BeanNameAware和BeanFactoryAware

来源:互联网 发布:千牛苹果mac版 编辑:程序博客网 时间:2024/05/07 19:33

BeanNameAware和BeanFactoryAware

1.BeanNameAware和BeanFactoryAware概念

BeanNameAware:实现该接口的Bean能够在初始化时知道自己在BeanFactory中对应的名字。

BeanFactoryAware:实现该接口的Bean能够在初始化时知道自己所在的BeanFactory的名字。

2.继续前面文章的分析,看这一段源码:


initializeBean方法,前面的文章已经分析过了,上图中的applyBeanPostProcessorsBeforeInitialization也分析了。 这个invokeAwareMethods就是对继承Aware接口的Bean进行初始化,再看下图:


也就是说继承BeanNameAware接口的会获得Bean名称,继承BeanFactoryAware接口的会获得BeanFactory名称。

3.在App.java中继承上述两个接口,并且打印相关信息:

package com.mycompany.app;import java.util.HashMap;import java.util.Map;import org.springframework.beans.BeansException;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.BeanFactoryAware;import org.springframework.beans.factory.BeanNameAware;import org.springframework.beans.factory.FactoryBean;import org.springframework.beans.factory.InitializingBean;public class App implements InitializingBean,FactoryBean<Object>,BeanNameAware,BeanFactoryAware{private App(){System.out.println("App.App()");}private  String says="App";    public String getSays() {return says;}public void setSays(String says) {this.says = says;}public void say(){    System.out.println("App.app():"+says);    }/*如在源码中看到的,在getset之后,在BeanPostProcessor的after方法之前执行*/public void setBeanName(String name) {System.out.println("App.setBeanName():"+name);}/*如在源码中看到的,在getset之后,在BeanPostProcessor的after方法之前执行*/public void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("App.setBeanFactory():"+beanFactory);}/** * 在构造函数和getset方法之后执行postProcessBeforeInitialization方法 *//*这个方法是InitializingBean在继承InitializingBean接口后,要实现的方法,顾名思义,是在 *属性设置之后进行一些操作*/public void afterPropertiesSet() throws Exception {System.out.println("App.afterPropertiesSet()");}/*这个方法是在Spring配置中通过init-method属性指定为该方法,然后才会执行,在afterPropertiesSet方法之后*/public void initMethod(){System.out.println("App.initMethod()");}/** *在afterPropertiesSet和initMethod方法之后执行postProcessAfterInitialization方法 *//*FactoryBean测试*/public Object getObject() throws Exception {System.out.println("App.getObject()");Map<String,Object> map = new HashMap<String, Object>();map.put("test", "GetObject");return map;}@SuppressWarnings("rawtypes")public Class<?> getObjectType() {return new HashMap().getClass();}public boolean isSingleton() {return true;}}

其他几个文件前面贴过,这里再贴上来:

BeanFactoryPostProcessorApp.java

package com.mycompany.app;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;public class BeanFactoryPostProcessorApp implements BeanFactoryPostProcessor{private BeanFactoryPostProcessorApp() {System.out.println("BeanFactoryPostProcessorApp.BeanFactoryPostProcessorApp()");}public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition = (BeanDefinition)beanFactory.getBeanDefinition("app");beanDefinition.setAttribute("says", "BeanFactoryPostProcessor");System.out.println("BeanFactoryPostProcessorApp.postProcessBeanFactory(): "+beanDefinition.getAttribute("says"));}}

BeanPostProcessorApp.java

package com.mycompany.app;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;public class BeanPostProcessorApp implements BeanPostProcessor{/*如果打印结果出现该字符串,证明进行了初始化*/private BeanPostProcessorApp(){System.out.println("BeanPostProcessorApp.BeanPostProcessorApp()");}public Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {if(bean instanceof App){((App)bean).setSays("Before:BeanPostProcessorApp");System.out.println("BeanPostProcessorApp.postProcessBeforeInitialization()");}return bean;}public Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {if(bean instanceof App){((App)bean).setSays("After:BeanPostProcessorApp");System.out.println("BeanPostProcessorApp.postProcessAfterInitialization()");}return bean;}}

SpringBean.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" xmlns:context="http://www.springframework.org/schema/context"      xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"      xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd          http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">               <bean id="app" class="com.mycompany.app.App" init-method="initMethod"></bean>      <bean id="beanPostProcessorApp" class="com.mycompany.app.BeanPostProcessorApp"></bean>    <bean id="beanFactoryPostProcessorApp" class="com.mycompany.app.BeanFactoryPostProcessorApp"></bean></beans>

BeanFactoryPostProcessorAppTest.java

package com.mycompany.app;import java.util.Map;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanFactoryPostProcessorAppTest {public static void main(String[] args) {    @SuppressWarnings("resource")ApplicationContext applicationContext = new ClassPathXmlApplicationContext("SpringBean.xml");         Map map = (Map)applicationContext.getBean("app");          System.out.println("BeanFactoryPostProcessorAppTest.main():"+map.get("test").toString());}}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.mycompany.app</groupId>  <artifactId>myapp</artifactId>  <packaging>jar</packaging>  <version>1.0-SNAPSHOT</version>  <name>myapp</name>  <url>http://maven.apache.org</url>    <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>4.1.3.RELEASE</spring.version>  </properties>    <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>   <dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency>  </dependencies>  </project>

然后运行BeanFactoryPostProcessorAppTest.java,结果如下:


4.梳理下执行顺序:

BeanFactory接口 -> Bean构造函数 -> Bean的GetSet方法 -> Aware接口 -> BeanPostProcessor的Before方法

-> afterPropertiesSet -> initMethod -> BeanPostProcessor的After方法 -> FactoryBean的getObject方法

0 0
原创粉丝点击