【spring除了XML配置外,还有注解类配置,这个就主要讲注解类配置】
package com.abc.config; import com.abc.condition.LinuxCondition; import com.abc.condition.WindowsCondition; import com.abc.domain.Color; import com.abc.domain.Person; import com.abc.domain.Student; import com.abc.myTypeFilter; import org.springframework.context.annotation.*; import org.springframework.context.annotation.ComponentScan.Filter; /** * excludeFilters 排除过滤容器的对象 * includeFilters 包含容器对象 */ /** * 一个 ComponentScans 【这个带 s 哦】 里面有个属性为 value,value是个集合,可以有多个ComponentScan属性,然后再...... * * 【value = "com.abc" ;它的作用是扫描这个包下的,但是是否加入包含还是排斥,需要后面的代码了】 * * excludeFilters:不包含过滤-->即 Filter注解上的都不加载进容器 * includeFilters: 包含过滤---->即 Filter注解上的才会加载进容器 * FilterType.ANNOTATION 表示注解类型的 即例如 Controller.class,Component.class ,Service.class 等等类型 * FilterType.ASSIGNABLE_TYPE 表示指定类型的 即如我自己写的Student类型【Student.class】 StudentController类型【StudentController.class】等等 * FilterType.ASPECTJ 表示Aspect类型的 ,几乎不用 * FilterType.REGEX 表示满足正则表达式的, * FilterType.CUSTOM 表示使用自定义规则 创建实现TypeFilter实现类,若返回true,加入容器,返回false,不让加入容器 */ /*@ComponentScans(value = { @ComponentScan(value = "com.abc",excludeFilters = { @Filter(type = FilterType.ANNOTATION,classes = {Controller.class}) }) })*/ /*@ComponentScans(value = { @ComponentScan(value = "com.abc",includeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Student.class}) }) })*/ @Configuration @ComponentScans(value = { @ComponentScan(value = "com.abc",excludeFilters = { @Filter(type = FilterType.CUSTOM,classes = {myTypeFilter.class}) },useDefaultFilters = false) }) /** * 【使用第三种方式给容器导入组件使用---->>Import】 */ @Import(Color.class) public class myConfig { /** * @Scope作用是否是单例 * * singleton: 单例的(默认值)Ioc容器启动会调用方法创建对象放到Ioc容器中,以后调用直接从容器中拿 * prototype: 多实例的,Ioc容器并不会去调用方法创建对象放在容器中 * request: 同意一次请求创建一个实例 * session: 同一个Session会话 */ @Scope("singleton") @Bean public Student student(){ Student student = new Student("张三", "男", 23); return student; } /** * @Conditional * @return */ @Conditional(WindowsCondition.class) @Bean("bill") public Person person01(){ return new Person("李四",24); } @Conditional(LinuxCondition.class) @Bean("linux") public Person person02(){ return new Person("王五",25); } /** * 使用第三种方式给容器导入组件使用---->>Import * 1. 在配置类上加 Import(类的class对象)这是个数组,可以多个 * 2. 还可以实现 【ImportSelector】 接口,然后在实现类添加需要加入容器的组件,注意加入的是 类的全限定名 * 3. 还可以实现ImportBeanDefinitionRegistrar 接口:手动注册 */ }
【使用自定义规则】
import org.springframework.core.io.Resource; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.ClassMetadata; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; import java.io.IOException; public class myTypeFilter implements TypeFilter { /** * metadataReader : 读取到的当前类扫描到的信息 * metadataReaderFactory: 可以获取到其他任何类型的 */ @Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //获取当前类注解信息 AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //获取当前正在扫描的类信息 ClassMetadata classMetadata = metadataReader.getClassMetadata(); //湖区当前类资源(类的路径) Resource resource = metadataReader.getResource(); //获取当前正在扫描的类的名字 String className = classMetadata.getClassName(); /* if (className.contains("er")){ System.out.println(" *********************"+className); return true; }*/ return false; } }
1.注解@Bean
2.注解@Condition
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; public class LinuxCondition implements Condition { /** * ConditionContext :上下文信息 * AnnotatedTypeMetadata:获取当前类注解信息 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //1 获取到Ioc使用的BeanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //2 获取类加载器 ClassLoader classLoader = context.getClassLoader(); //3 获取环境信息 Environment environment = context.getEnvironment(); //4 获取到Bean 定义的注册类 BeanDefinitionRegistry registry = context.getRegistry(); String property = environment.getProperty("os.name"); if (property.contains("linux")){ return true; } return false; } }
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; public class WindowsCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //1 获取到Ioc使用的BeanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //2 获取类加载器 ClassLoader classLoader = context.getClassLoader(); //3 获取环境信息 Environment environment = context.getEnvironment(); //4 获取到Bean 定义的注册类 BeanDefinitionRegistry registry = context.getRegistry(); String property = environment.getProperty("os.name"); if (property.contains("Windows")){ return true; } return false; } }
3.注解@Import
4.实现 ImportSelector 接口
5.实现 ImportBeanDefinitionRegistrar 接口
import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.type.AnnotationMetadata; public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /** * AnnotationMetadata: 当前类大注解信息 * BeanDefinitionRegistry: BeanDefinition注册类 * 把所有需要添加到容器的中的Bean: 调用 * BeanDefinitionRegistry.registryBeanDefinition手工注册进来 */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean red = registry.containsBeanDefinition("red"); boolean blud = registry.containsBeanDefinition("blud"); //如果容器中有 【red】 和【blud】两个组件,就把下面的组件加入容器 if (red && blud){ RootBeanDefinition beanDefinition = new RootBeanDefinition(); //注册一个Bean,并且制定bean名称 registry.registerBeanDefinition("raidBow",beanDefinition); } } }
6.实现 FactoryBean<> 接口
import com.abc.domain.Color; import org.springframework.beans.factory.FactoryBean; public class myFactoryBean implements FactoryBean<Color> { //返回一个对象,这个对象会被添加到容器中 @Override public Color getObject() throws Exception { return new Color(); } //从容器拿出组件时的类型 @Override public Class<?> getObjectType() { return Color.class; } //报存是否为单例 ,如果是true 就是单例,返回false就是非单例 @Override public boolean isSingleton() { return false; } }
原文:https://www.cnblogs.com/lcj12121/p/11434542.html