0.2、Spring 源码学习:从BeanNameAware 到 *Aware 认识一个Spring bean

版权声明:欢迎转载交流,声明出处即可。体能状态先于精神状态,习惯先于决心,聚焦先于喜好 ——Bestcxx https://blog.csdn.net/bestcxx/article/details/90521143

前言

体能状态先于精神状态,习惯先于决心,聚焦先于喜好

Aware:感知

org.springframework.beans.factory.Aware 是 Spring 提供的一个接口
该类注释对这个接口对介绍是:
一个超级接口,其表示一个 bean 能够合格对被一个特殊对框架对象——Spring 容器,通过 callback-style 对方法进行通知.
这个接口对实现都是由子类完成的,典型的组成部分是一个 void 返回类型的set 方法
由于这个接口不提供任何默认的抽象方法,所以子类必须明确的做一些事情,比如在 org.springframework.beans.factory.config.BeanPostProcessor 中.
可以参考 BeanPostProcessor 的两个实现类,org.springframework.context.support.ApplicationContextAwareProcessor 和 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory,其中有对 *Aware 对应用例子
这里 *Aware 表示 Aware 有很多子接口,比如 BeanNameAware,BeanFactoryAware,BeanClassLoaderAware,EnvironmentAware

继承 Aware 的 子接口

很多,比如 BeanNameAware 接口,就是感知Spring Bean 的Name的
BeanClassLoaderAware 接口就是感知 Spring Bean 的类加载器的
这些接口需要被你自己写的Spring bean 实现,然后覆盖重写set 方法
此外,有一些是全局的属性,可以用注入的方式获得,比如 EnvironmentContextAware

在这里插入图片描述

从BeanNameAware 说起

org.springframework.beans.factory.BeanNameAware
来自注释的内容:一个被beans 实现的接口,用于获得这些 bean 在bean factory 中的名字.
但是通常来讲,一个对象的使用并不建议依赖这个bean的名字,而且依赖一个Spring API 会新增潜在脆弱的配置,这是没有必要的
类似的接口如同上图所示

用法举例

写一个 Spring Bean 实现几个 *Aware 接口

这些接口的确都只有一个 set 方法,我们可以获得 Spring 容器基于这个 bean 相关的信息,这里我只是打印出来,当然你也可以有其他操作
这里我们获得被加载的这个 Spring bean 在Spring 容器中的 bean name、类加载器、管理这个Spring bean 的 Spring factory-最为神奇经典的DefaultListableBeanFactory

package com.bestcxx.stu.test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;

/**
 *  Aware 感知
 *  测试类加载时 BeanNameAware、BeanFactoryAware、BeanClassLoaderAware 被调用的set 方法
 * @author jie.wu
 *
 */
@Component
public class AInterfaceImpl implements BeanNameAware,BeanFactoryAware,BeanClassLoaderAware {
	
	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		System.out.println("我的类加载器是"+classLoader);
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("我的 beanFactory 是"+beanFactory);
	}

	@Override
	public void setBeanName(String name) {
		System.out.println("我的 BeanName 是"+name);
	}
}
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:tx="http://www.springframework.org/schema/tx"    
    xmlns:aop="http://www.springframework.org/schema/aop"    
    xmlns:util="http://www.springframework.org/schema/util"    
    xmlns:orm="http://www.springframework.org/schema/orm"     
    xmlns:mvc="http://www.springframework.org/schema/mvc"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd    
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd    
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd    
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd    
                        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd    
                        http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-4.3.xsd    
                        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd    
    "
    >  
    <context:component-scan base-package="com.bestcxx.stu.test"/>
</beans>  
测试方法
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AInterfaceTest {
	
	/**
	 * 只要加载配置文件就会自动加载 bean
	 */
	@Test
	public void test() {
		ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:test/applicationcontext-test.xml");
	}
}

测试结果
我的 BeanName 是AInterfaceImpl
我的类加载器是sun.misc.Launcher$AppClassLoader@4b1210ee
我的 beanFactory 是org.springframework.beans.factory.support.DefaultListableBeanFactory@76b10754: ...

我在源码中看到类三个特殊的 *Aware

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
中,有下面一段代码,显示BeanNameAware、BeanFactoryAware 和 BeanClassLoaderAware ,含义是忽略对这三个接口的依赖

public AbstractAutowireCapableBeanFactory() {
	super();
	ignoreDependencyInterface(BeanNameAware.class);
	ignoreDependencyInterface(BeanFactoryAware.class);
	ignoreDependencyInterface(BeanClassLoaderAware.class);
}

猜你喜欢

转载自blog.csdn.net/bestcxx/article/details/90521143