@ComponentScan

@SpringBootApplication
这个注解是一个符合注解 包含了

@ComponentScan(excludeFilters = { @Filter(type = FilterType.**_CUSTOM_**, classes = TypeExcludeFilter.**class**),<br /> @Filter(type = FilterType.**_CUSTOM_**, classes = AutoConfigurationExcludeFilter.**class**) })
这里配置了需要扫描什么包 需要注意 @ComponentScan 有很多的默认值
image.png
这个属性设置为false 就可以不引入Controller 等注解标注的类
image.png
可以配置类,正则表达式 注解 还可以实现TypeFilter 接口来自定义。
image.png
image.png
这里默认要扫描 这四个注解所标识得类 都会被扫描进入ioc容器
多个 @ComponentScan 可能会相互影响。如果引入的jar包中有这个注解 需要注意

@Scope

标注再bean上 如果value 是singleton 就是单实例 默认也是 prototype就是多实例的。
单实例的时候默认容器初始化的时候就创建好了所有的bean prototype 每次都创建新的bean
image.png

@Lazy

是否懒加载 ,针对单实例。 让单实例的bean在使用的时候再去创建。第二次直接从容器中获得bean。

@Condition

这个注解只有一个value 值
这个值需要实现 Condition 接口 其中要是实现该接口
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
返回true 加入容器 。

@Import

@Import({MyImportSelector.class, MyImportRegistrar.class})
value 一个参数 是一个class的数组
参数有两种形式

  • 一种实现 ImportSelector 接口

@Override<br />**public **String[] selectImports(AnnotationMetadata importingClassMetadata) {<br /> **return new **String[]{ImportClazz1.**class**.getName(), ImportClazz2.**class**.getName()};<br />} 返回的就是需要加入容器的类

  • 另一种实现 ImportBeanDefinitionRegistrar

`@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

  1. BeanDefinitionBuilder builder = BeanDefinitionBuilder._genericBeanDefinition_(ImportClazz3.**class**);<br /> registry.registerBeanDefinition(**"importClazz3"**,builder.getBeanDefinition());

}` BeanDefinitionRegistry 直接向容器中注册bean

@Bean

@Bean(value = **"person"**,destroyMethod = **"destroy"**,initMethod = **"init"**)<br />**public **Person person(){<br /> Person person = **new **Person();<br /> **return **person;<br />}

  • value Bean的名字
  • destroyMethod 销毁调用的函数 同@PostConstruct 标注的函数的效果
  • initMethod 初始化 调用函数 同 @PreDestroy 标注的函数的效果

    @PostConstruct实现的原理

  • 调用refresh();

  • 调用

_// Instantiate all remaining (non-lazy-init) singletons.<br />_finishBeanFactoryInitialization(beanFactory);//

  • getBean(beanName);
  • doGetBean(name, null, null, false);
  • singletonFactory.getObject();
  • createBean(beanName, mbd, args);
  • doCreateBean(beanName, mbdToUse, args); 从这开始重点
    • populateBean(beanName, mbd, instanceWrapper); 在这里边给bean属性赋值
  • initializeBean(beanName, exposedObject, mbd); // 初始化bean
    • 实现了Aware接口的相关bean 执行 invokeAwareMethods(beanName, bean);
    • applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    • 找到所有的 PostProcessor 遍历执行 postProcessBeforeInitialization 在这里执行了方法
      • 因为有CommonAnnotationBeanPostProcessor 继承了 InitDestroyAnnotationBeanPostProcessor
        • 执行其中的postProcessBeforeInitialization

`@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
}

`

  • invokeInitMethods() 执行目标方法
  • init()方法执行

    initMethod 实现原理

  • 到initializeBean(beanName, exposedObject, mbd); // 初始化bean 一样 后面不一样
  • 进入初始化 在applyBeanPostProcessorsBeforeInitialization 之后调用了
    • t**ry **{<br /> invokeInitMethods(beanName, wrappedBean, mbd);<br />}函数
  • invokeCustomInitMethod(beanName, bean, mbd); 执行初始化函数

  • 上面两个函数的实现等同于让bean实现InitializingBean 和DisposableBean 两个接口

`@Override
public void destroy(){ //DisposableBean 接口必须实现
System.out.println(“销毁得时候得 destroy 函数执行了”);

}

@Override
public void afterPropertiesSet() throws Exception {<br />//InitializingBean 必须要实现的方法
System.out.println(“初始化函数 afterPropertiesSet 的执行”);

}`

  • 实现的流程 和上面initMethod 一样 只是最后 不是在 invokeInitMethods 中的invokeCustomInitMethod方法中执行的 在这个方法执行之前执行了 ((InitializingBean) bean).afterPropertiesSet();在这执行了方法