Spring的IOC实现分析
BeanFactory接口体系简单分析
- AnnotationConfigApplicationContext继承体系
-
BeanFactory接口的继承体系
继承自BeanFacrtory接口的接口
-
HierarchicalBeanFactory
-
AutowireCapableBeanFactory
-
ListableBeanFactory
bean中的基本功能:
- bean的获取:
- 按照id名称获取
- 按照类型获取
- 按照id+类型获取
- bean的供应商
- bean的基本信息:
- 是否存在
- 是否单例
- 类型获取
- 类型检测
- 别名获取
-
-
HierarchicalBeanFactory接口作用
-
分别为dao层,service层,web层提供一个容器,并且存在逻辑上的继承关系,在service层可以获得dao层的bean,在web层可以获得前面两层的bean
-
对传递进来的bean实现分层管理
-
提供bean的分层结构,提出父子容器的概念
- 获得本地的bean
-
-
AutowireCapableBeanFactory接口
- 在进行依赖注入的时候自动注入该bean创建需要的资源
- 自动装配:
- 装配方式
- 前置动作
- 后置动作
-
ListableBeanFactory接口
- 提供遍历搜索容器中bean的信息
- 容器中bean的信息
- bean是否存在
- bean的数量
- bean的类型
- bean相关的信息获取
- 由类型获取bean的名称
- 由注解获取bean的名称
- bean的信息的获取
- bean的注解
- bean的定义名称
- 容器中bean的信息
- 提供遍历搜索容器中bean的信息
组件扫描器
-
在开发中如一个service层的功能由许多个组件的功能组合而成,表现层的bean是由业务层bean+数据访问层bean+日志bean,但是我们在进行测试的时候可能因为一些需求或者限制导致我们不能使用一些bean或者一些bean使用不了,那么就需要我们在执行相关功能的时候让spring去加载指定的一些容器,那么就需要使用组件扫描器,
-
使用:使用开启注解解析注解中的excludeFilters的属性【按照规则过滤】includeFilters【按照规则加载】
@ComponentScan( value = "com.wx", // 扫包解析注解 excludeFilters = @ComponentScan.Filter( type = FilterType.ANNOTATION, // 过滤的方式 按照注解过滤 classes = Service.class // 要被过滤掉的对象 ) )
type取值:
public enum FilterType { ANNOTATION, // 按照注解过滤 ASSIGNABLE_TYPE, // 指定类型过滤 ASPECTJ, REGEX, // 正则表达式 CUSTOM; // 用户自定义 private FilterType() { } }
-
自定义过滤
// 自定义一个类实现TypeFilter接口 public class MyTypeFilter implements TypeFilter { /** * 自定义拦截规则 * @param metadataReader 普通要注入的依赖的元数据 * @param metadataReaderFactory 工厂依赖注入的元数据 * @return 表示是否拦截 true表示拦截 * @throws IOException */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { /** * 自定义实现拦截指定类不然加载 */ ClassMetadata classMetadata = metadataReader.getClassMetadata(); // 要注入的依赖的类的元数据 if(classMetadata.getClassName().equals("com.wx.test.TestONE")){ // 如果注入的数据类型是要过滤的类型返回true return true; }else { return false; } } }
使用自定义过滤器:
@ComponentScan( value = "com.wx", // 扫包解析注解 excludeFilters = @ComponentScan.Filter( // type = FilterType.ANNOTATION, // 过滤的方式 // classes = Service.class // 要被过滤掉的对象 type =FilterType.CUSTOM, classes = MyTypeFilter.class ) )
自定义导入器
-
bean的加载方式使用xml的方式加载或者使用注解的方式加载
-
在开发的时候通常需要大量的bean需要加载到IOC容器中,自动加载的方式比较慢,可以自定义加载方式进行快速高效的加载bean
-
制作方式:
-
自定义一个类实现ImportSelector
-
在类中指定要加载的类的全路径
-
在spring的和兴配置类使用@Import(自定义加载的class类)
public class MyImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 1.编程形式加载一个类 // return new String[]{"com.wx.dao.impl.BookDaoImpl"}; // 2.加载import.properties文件中的单个类名 // ResourceBundle bundle = ResourceBundle.getBundle("import"); // String className = bundle.getString("className"); // 3.加载import.properties文件中的多个类名 ResourceBundle bundle = ResourceBundle.getBundle("import"); String className = bundle.getString("className"); return className.split(","); } }
-
Bean初始化解析过程
- 创建工厂与初始化阶段
- BeanFactoryPosterProcess在初始化工厂之前或者以后进行一些操作
- bean创建与初始化
ame");
return className.split(",");
}
}
Bean初始化解析过程
- 创建工厂与初始化阶段
- BeanFactoryPosterProcess在初始化工厂之前或者以后进行一些操作
- bean创建与初始化
- BeanPosterProcessor这个接口定义bean在初始化与初始化结束以后要执行的操作