给容器注册组件的三种方式
- 包扫描+组件标记注解(@Component @Control @Repository),这是自己写的类常用这种方式
- @Bean [ 导入的第三方包里面的组件 ]
- @Import [快速给容器注册组件] id默认是全类名
文章目录
- 给容器注册组件的三种方式
- Spring注解驱动开发
- 组件(bean)注册@Configuration@Bean注解
- ComponentScan注解
- 注意点
- 自定义TypeFilter指定过滤规则
- 懒加载@Lazy注解
- @Conditional注解-按照条件注册Bean
- @Import给容器中快速导入一个组件
- @Import-使用ImportSelector
- @Import-使用@ImportBeanDefinitionRegister注册组件
- 使用FactoryBean注册组件
- 生命周期
- BeanPostProcessor后置处理器
- @Value注解
- @Autowired
- @Resource @Inject
- @Profile:指定组件在哪个环境的情况下才能被注册到容器中
Spring注解驱动开发
组件(bean)注册@Configuration@Bean注解
用xml给Person类注册到容器中,并赋属性值
ComponentScan注解
作用
在测试类中加载bean.xml时,如果是用@Component注解注册组件到容器中,则在xml中必须要加一个context:component-scan标签
<context:component-scan base-package=“a/b” 这个标签的作用是扫描a/b包及其子包下所有类的注解,这样那些类上的注解才会被识别到
可以用@ComponentScan注解代替context:component-scan标签
注意点
自定义TypeFilter指定过滤规则
public enum FilterType {
ANNOTATION,
ASSIGNABLE_TYPE,
ASPECTJ,
REGEX,
CUSTOM;
private FilterType() {
}
}
过滤的时候指定类型,这样@ComponentScan注解扫描的时候,就可以不用扫描所有的注解了
懒加载@Lazy注解
懒加载:在加载容器的时候,不创建对象。在使用的时候才创建对象,这时候就可以在@Bean注解上面加一个@Lazy注解
@Conditional注解-按照条件注册Bean
@Configuration
public class testaaa {
@Conditional()
@Bean
public Person hello(){
return new Person("zhan", 23);
}
}
点到Conditional源码里面去看
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
@Conditional注解需要传入一个数组,数组里面元素的类型为Class字节码,既然是字节码,那肯定是某个类的字节码呀,是哪个类呢?就是尖括号里面的实现Condition接口的实现类的字节码,所以我们要自己创建一个类,而且还要实现Condition接口
@Import给容器中快速导入一个组件
@Import-使用ImportSelector
这里并不是将MyImportSelector类导入到容器中,而是将这个类里面的selectImports方法的返回值,也就是一个String数组,将这个数组里面的所有元素都导入到容器中
@Import-使用@ImportBeanDefinitionRegister注册组件
public class MyImportDefinition implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Student.class);
registry.registerBeanDefinition("Student", rootBeanDefinition);
RootBeanDefinition rootBeanDefinition1 = new RootBeanDefinition(color.class);
registry.registerBeanDefinition("color", rootBeanDefinition1);
}
}
在配置类中将MyImportDefinition.class注册进去
@Configuration
@Import({MyImportDefinition.class}) // 这个@Import导入组件必须是空参构造
public class MyConfiguration {
}
使用FactoryBean注册组件
生命周期
通过@Bean指定init-Method和destory-Method
// 将要注入到容器中的Bean
public class color {
public void chushi(){
System.out.println("初始化");
}
public void destory(){
System.out.println("销毁color");
}
}
@ComponentScan("com.zzw")
@Configuration
public class MyConfiguration {
@Bean(initMethod = "chushi", destroyMethod = "destory")
public color color(){
return new color();
}
}
对象创建完成就立马调用initMethod指定的方法
public class Dog {
public Dog() {
System.out.println("狗对象创建完成");
}
@PostConstruct
public void init(){
System.out.println("对象创建之后");
}
@PreDestroy
public void destory(){
System.out.println("对象销毁之前");
}
}
初始化完成之后
狗对象创建完成
对象创建之后
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
myConfiguration
blue
dog
对象销毁之前
销毁
Process finished with exit code 0
BeanPostProcessor后置处理器
这个后置处理器是针对Spring容器里面所有的组件的,并不是针对某一个特定的bean
@Component
public class MybeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean+"创建之前"+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(bean+"创建之后"+beanName);
return bean;
}
}
@Value注解
@Autowired
@AutoWired注解里面的required属性=false时,这样上图中即使Spring容器中没有BookDao这个组件,也是不报错的!!