還記的我們?cè)?CreateBean(...)方法中其中有一個(gè)過(guò)程是初始化bean的過(guò)程,在初始化的方法中我們其中有一個(gè)過(guò)程是激活A(yù)ware的方法的過(guò)程,這節(jié)我們來(lái)看看Aware到底是什么
Aware接口
該接口位于org.springframework.beans.factory包下
/**
* A marker superinterface indicating that a bean is eligible to be notified by the
* Spring container of a particular framework object through a callback-style method.
* The actual method signature is determined by individual subinterfaces but should
* typically consist of just one void-returning method that accepts a single argument.
*
* <p>Note that merely implementing {@link Aware} provides no default functionality.
* Rather, processing must be done explicitly, for example in a
* {@link org.springframework.beans.factory.config.BeanPostProcessor}.
* Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
* for an example of processing specific {@code *Aware} interface callback
*/
public interface Aware {
}
該接口主要的作用是一個(gè)標(biāo)記超級(jí)接口,實(shí)現(xiàn)了該接口的bean是具有回調(diào)spring容器的能力,我們可以看到,是一個(gè)空接口,實(shí)際方法的簽名是由各個(gè)子接口來(lái)實(shí)現(xiàn),通常只接受返回單個(gè)參數(shù)的seter方法,我們來(lái)看一下我們的激活A(yù)ware方法的代碼:
AbstractAutowireCapableBeanFactory.java
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
代碼簡(jiǎn)單:
- 如果是BeanNameAware類(lèi)型的話,調(diào)用setXX方法設(shè)置屬性
- 如果是BeanClassLoaderAware類(lèi)型的話,調(diào)用setBeanClassLoader設(shè)置屬性
- 如果是beanFactoryAware類(lèi)型的話,調(diào)用setBeanFactory設(shè)置屬性
Aware的實(shí)現(xiàn)類(lèi)
我們來(lái)看一下實(shí)現(xiàn)了Aware接口的子類(lèi)
這只是其中的一部分實(shí)現(xiàn),圖來(lái)自大佬芋艿的博客,大家可以去看看,接下來(lái)我們自己可以實(shí)現(xiàn)自己的Aware方法:
''''''
public interface BeanClassLoaderAware extends Aware {
/**
* 將 BeanClassLoader 提供給 bean 實(shí)例回調(diào)
* 在 bean 屬性填充之后、初始化回調(diào)之前回調(diào),
* 例如InitializingBean的InitializingBean.afterPropertiesSet()方法或自定義init方法
*/
void setBeanClassLoader(ClassLoader classLoader);
public interface BeanFactoryAware extends Aware {
/**
* 將 BeanFactory 提供給 bean 實(shí)例回調(diào)
* 調(diào)用時(shí)機(jī)和 setBeanClassLoader 一樣
*/
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
public interface BeanNameAware extends Aware {
/**
* 在創(chuàng)建此 bean 的 bean工廠中設(shè)置 beanName
*/
void setBeanName(String name);
}
public interface ApplicationContextAware extends Aware {
/**
* 設(shè)置此 bean 對(duì)象的 ApplicationContext逸雹,通常,該方法用于初始化對(duì)象
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
常見(jiàn)的四種實(shí)現(xiàn)Aware接口的子類(lèi),我們來(lái)看case
public class MyAwareCase implements
BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, ApplicationContextAware {
private String beanName;
private ClassLoader classLoader;
private BeanFactory beanFactory;
private ApplicationContext applicationContext;
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
System.out.println("調(diào)用:BeanClassLoaderAware的setBeanClassLoader方法");
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("調(diào)用:BeanFactoryAware的setBeanFactory方法");
}
public void setBeanName(String name) {
this.beanName = name;
System.out.println("調(diào)用:BeanNameAware的setBeanName方法");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("調(diào)用:ApplicationContextAware的setApplicationContext方法");
}
public void display(){
System.out.println("beanName:" + beanName);
System.out.println("是否為單例:" + beanFactory.isSingleton(beanName));
System.out.println("系統(tǒng)環(huán)境為:" + applicationContext.getEnvironment());
}
測(cè)試方法如下:
public class AwareTest {
public static void main(String[] args) {
ClassPathResource resource = new ClassPathResource("awareConfig.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
MyAwareCase myAwareCase = (MyAwareCase)factory.getBean("myAwareCase");
myAwareCase.display();
}
配置文件如下:
<?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="myAwareCase" class="com.sgcc.aware.MyAwareCase">
<property name="beanName" value="beanName"/>
<property name="beanFactory" value="beanFactory"/>
<property name="beanClassLoader" value="beanClassLoader"/>
<property name="applicationContext" value="applicationContext"/>
</bean>
</beans>
很意外,我運(yùn)行時(shí)報(bào)了一個(gè)錯(cuò)誤,大概知道問(wèn)題所在,這里我把錯(cuò)誤貼出來(lái),有知道解決的可以留個(gè)言,在這里我先謝過(guò)了
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.beans.factory.BeanFactory' for property 'beanFactory'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.beans.factory.BeanFactory' for property 'beanFactory': no matching editors or conversion strategy found
at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590)
at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219)
從異常信息來(lái)看是因?yàn)閷傩詁eanFactory在匹配類(lèi)型的過(guò)程中出現(xiàn)的問(wèn)題.它需要的是一個(gè)BeanFactory類(lèi)型的屬性value,我這里是String,可能是這個(gè)原因造成的
總結(jié)
經(jīng)過(guò)簡(jiǎn)單的case,我們發(fā)現(xiàn)Aware接口的實(shí)質(zhì),spring主要來(lái)檢測(cè)當(dāng)前bean是否實(shí)現(xiàn)了Aware接口,如果實(shí)現(xiàn)了,則通過(guò)setxxx設(shè)置對(duì)應(yīng)的屬性給bean,之后我們的bean就有了從spring容器中獲取資源的權(quán)限了......