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方法