spring组件注册
Posted programmlover
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring组件注册相关的知识,希望对你有一定的参考价值。
一 给容器中注册bean
1、新建一个类,并在类上加上注解@Configuration,表明这是一个配置类。
1 @Configuration 2 public class MainConfig { 3 4 }
2、然后在配置类中添加一个带返回值的方法,并加上@Bean,表明注册该bean实例
@Bean() public Person getPerson() { Person person = new Person("张三", 22); return person; }
3、最后新建一个测试类,用AnnotationConfigApplicationContext(Class<?>... annotatedClasses)构造方法启动spring容器,就能得到配置类下的所有bean实例
public class MainTest { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class); Person person =(Person) context.getBean(Person.class); System.out.println(JSON.toJSONString(person)); String[] beanName = context.getBeanNamesForType(Person.class); System.out.println(Arrays.toString(beanName)); } }
这样一个bean就注册好了
注意:@Bean默认生成的bean的id是方法名,如果想要自定义bean的id,可以写为@Bean("placeholder"),这样就可以设置该bean的id
二 启动注解扫描
1、在@Configuration的类下添加@ComponentScan即可启动注解扫描。
2、@ComponentScan的用法为:
String[] value() default {} //扫描指定包下的注解
Filter[] excludeFilters() default {} //排除Filter指定的过滤规则
Filter[] includeFilters() default {} //只包含Filter指定的过滤规则,注意:使用includeFilters必须还得加上useDefaultFilters=false才能生效
boolean useDefaultFilters() default true //是否使用默认过滤规则,只有设置为false,includeFilters才会生效
3、@Filter的用法为:
FilterType type() default FilterType.ANNOTATION
/*FilterType 枚举类型,包含:
* ANNOTATION //按照注解过滤
* ASSIGNABLE_TYPE //按照给定的类过滤
* ASPECTJ //按照ASPECTJ表达式过滤,不常用
* REGEX //按照正则表达式过滤
* CUSTOM //使用自定义规则过滤,使用这种过滤规则,Classes必须包含自定义的实现了 org.springframework.core.type.filter.TypeFilter 的类
*/
@AliasFor("value") Class<?>[] classes() default {}; //指定要过滤的类
String[] pattern() default {}; //指定要过滤的表达式语句
4、示例:
@ComponentScan(value="com.dj", excludeFilters= {
@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})
}) //指定扫描com.dj下的注解,但排除@Controller注解
@ComponentScan(value="com.dj", includeFilters= {
@Filter(type=FilterType.ANNOTATION,classes= {Controller.class})
}, useDefaultFilters=false) //指定扫描com.dj下的注解,但只扫描@Controller注解
5、还可以用 @ComponentScans(value= { }) 设置多个ComponentScan
注意:@ComponentScan不会对@Configuration指定的类和类中的方法生效
三 自定义过滤规则
1、使用自定义过滤规则,Filter必须设置成 @Filter(type=FilterType.CUSTOM, classes= {MyTypeFilter.class}) ,其中 MyTypeFilter 是实现了 org.springframework.core.type.filter.TypeFilter的类
2、示例:
@ComponentScan(value="com.dj", includeFilters= {
@Filter(type=FilterType.CUSTOM, classes= {MyTypeFilter.class})
} //指定扫描com.dj下的注解,过滤规则为 MyTypeFilter 指定的过滤规则
3、MyTypeFilter写法为:
public class MyTypeFilter implements TypeFilter{ /** * 设置匹配规则:过滤掉类名不包含"er"的类 * metadataReader:读取当前类的信息 * metadataReaderFactory:可以获取任何类的信息 * return true:表示不过滤此类 * false:表示过滤此类 */ @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(); System.out.println("----->"+className); if(className.contains("er")) { return true; } return false; } }
四 @Scope设置bean的作用域
1、用法:@Scope("placeholder") ,其中placeholder可以设置成:
prototype //基于原型创建,多实例,IOC容器并不会创建方法创建对象放在容器中,只有在每次调用时才会创建
singleton //基于单例创建,单实例(默认值),IOC容器会调用方法创建对象放到IOC容器中,以后每次调用直接从容器中获取
request //同一个请求创建一个实例,不常用
session //同一个session创建一个实例,不常用
五 @Lazy设置bean的懒加载
1、单实例默认在容器启动是创建bean,@Lazy只针对单实例的bean,可以设置单实例在容器启动是不创建,在第一次使用时才创建,
用法:
@Lazy
六 @Conditional,按照条件给容器注册bean
1、@Conditional可以加到任何bean(无论类还是方法)上,只有条件成立时才创建bean,用法:
@Conditional({MyCondition.class}) // MyCondition 必须是实现 org.springframework.context.annotation.Condition 的类
2、示例:
@Conditional({MyCondition.class}) @Bean("testPerson") public Person getPerson00() { Person person = new Person("testEnvironment", 22); System.out.println(JSON.toJSON(person)); return person; }
3、MyCondition示例:
public class MyCondition implements Condition{ /** * 条件为os为Windows是返回true * @param context : 判断条件能够使用的上下文 * @param metadata: @Conditional的注解信息 * @return true: 条件成立,创建bean * false: 条件不成立,不创建bean */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { //获取IOC使用的beanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //获取类加载器 ClassLoader classLoader = context.getClassLoader(); //获取环境信息 Environment environment = context.getEnvironment(); //获取bean定义的注册类 BeanDefinitionRegistry registry = context.getRegistry(); String osName = environment.getProperty("os.name"); if(osName.toLowerCase().contains("windows")) { return true; } return false; } }
六 @Import 快速导入组件
1、@Import 用于快速导入组件,用于被@Configuration标注的配置类上
2、用法:
@Import({Placeholder.class,...}) //创建指定类的bean,默认bean的id为类的全类名(包名+类名)
七 ImportSelector 导入组件
1、ImportSelector是一个接口,所有实现 ImportSelector 的类只要放入 @Import 中spring就会自动创建 selectImports 方法返回的全类名的bean
2、@Import示例:
@Import({MyImportSelector.class}) //