spring之Aware接口详细分析

1:接口

接口为org.springframework.beans.factory.Aware,源码如下:

org.springframework.beans.factory.Aware
public interface Aware {
}

这是一个标记接口,表达的含义是当前bean具备了被告知某些信息的资格,但是具体告知什么,就是具体的子接口来定义了,比如org.springframework.beans.factory.BeanNameAware代表具备了被告知自己的名称的资格,此时需要来告知bean自己的名字是什么,比如org.springframework.beans.factory.BeanFactoryAware代表bean具备了被告知自己所在bean工厂容器对象的资格,此时需要告知bean工厂信息,但是仅仅是实现了告知具体信息的Aware接口并不会自动执行告知,这个告知的过程需要通过编码来完成,比如BeanNameAwareBeanFactoryAware就是在spring bean执行initializeBean方法时通过如下代码完成的:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
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);
		}
	}
}

除了这种固定方式,还可以通过BeanPostProcessor来实现。

2:子类

2.1:子类

只是拿几个子类来说明,其子类是非常非常多的。

  • BeanClassLoaderAware
org.springframework.beans.factory.BeanClassLoaderAware
public interface BeanClassLoaderAware extends Aware {
	// 回调提供加载类的ClassLoader信息
	// 调用的时机是,填充bean属性(即调用populateBean方法)后
	//,执行InitializingBean#afterPropertiesSet和init-method前 
	void setBeanClassLoader(ClassLoader classLoader);
}
  • BeanFactoryAware
org.springframework.beans.factory.BeanFactoryAware
public interface BeanFactoryAware extends Aware {
	// 会调用提供拥有bean实例的工厂IOC容器,调用的时机是:
	// 在调用方法populateBean填充bean属性之后,
	// 调用方法InitializingBean#afterPropertiesSet,init-method前
	// 传入的参数beanFactory肯定是直接可用的,绝对不会为null
	void setBeanFactory(BeanFactory beanFactory) throws BeansException;

}
  • BeanNameAware
org.springframework.beans.factory.BeanNameAware
// 想要从bean工厂容器中获取自己的bean名称,可以实现该接口
// ,但是注意不要依赖与bean名称来执行或者是控制业务逻辑
// 因为bean名称是依赖于外部配置的,而外部配置是随时可能改变的
public interface BeanNameAware extends Aware {
	// 设置bean所在的bean工厂中的bean名称,执行时机是:
	// 设置bean属性之后,执行InitializingBean#afterPropertiesSet,
	// 和init-method方法之前
	void setBeanName(String name);

}
  • ApplicationContextAware
org.springframework.context.ApplicationContextAware
public interface ApplicationContextAware extends Aware {

	/**
	 * Set the ApplicationContext that this object runs in.
	 * Normally this call will be used to initialize the object.
	 * <p>Invoked after population of normal bean properties but before an init callback such
	 * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
	 * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
	 * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
	 * {@link MessageSourceAware}, if applicable.
	 * @param applicationContext the ApplicationContext object to be used by this object
	 * @throws ApplicationContextException in case of context initialization errors
	 * @throws BeansException if thrown by application context methods
	 * @see org.springframework.beans.factory.BeanInitializationException
	 */
	// 设置bean所在的应用程序上下文对象,调用时机是:
	// 执行populateBean方法填充bean属性后,
	// 执行InitializingBean#afterPropertieSet,init-method方法前
	// 执行ResourceLoaderAware#setResourceLoader前,
	// 执行ApplicationEventPublisherAware#setApplicationContextEventPublisher前
	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

}

2.2:例子

public class TestAware implements BeanNameAware, BeanFactoryAware,
        ApplicationContextAware, BeanClassLoaderAware {
    private ClassLoader classLoader;
    private BeanFactory beanFactory;
    private String name;
    private ApplicationContext applicationContext;

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
        System.out.println("TestAware.setBeanClassLoader");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
        System.out.println("TestAware.setBeanFactory");
    }

    @Override
    public void setBeanName(String name) {
        this.name = name;
        System.out.println("TestAware.setBeanName, name is: " + this.name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        System.out.println("TestAware.setApplicationContext");
    }

    public void display(){
        System.out.println("beanName:" + name);
        System.out.println("是否为单例:" + beanFactory.isSingleton(name));
        Environment environment = applicationContext.getEnvironment();
        System.setProperty("spring.active.profiles", "online");
        String activeProfiles = environment.getProperty("spring.active.profiles");
        System.out.println(activeProfiles);
    }
}
  • 测试
@Test
public void testaware() {
    ClassPathXmlApplicationContext ac
            = new ClassPathXmlApplicationContext("testaware.xml");
    TestAware testAware = ac.getBean("testAware", TestAware.class);
    testAware.display();
}
  • 运行
TestAware.setBeanName, name is: testAware
TestAware.setBeanClassLoader
TestAware.setBeanFactory
TestAware.setApplicationContext
beanName:testAware
是否为单例:true
online
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值