@Bean 容器中注册组件
@Primary 同类组件如果有多个,标注组件
@DependsOn 组件之间的申明依赖
@Lazy 组件懒加载(最后使用的时候才创建)
@Scope 申明组件的作用范围(SCOPE_PROTOTYPE,SCOPE_SINGLETON)
@Configuration 申明一个配置类,替换以前的配置文件
@Component @Controller @Service @Respository 申明一个组件
@Indexed 加速注解的启动,所有加了@Indexed组件,都会直接快速启动
@Order 数字越小优先级越高
@ComponentScan 包扫描
@Conditional 条件注入
@Import 导入第三方jar的组件,或者定制批量导入组件逻辑
@ImportResource 导入以前的.xml配置文件
@Profile 基于多环境激活
@PropertySource 外部properties配置文件和JavaBean进行绑定,结合@ConfigurationProperties
@PropertySources @PropertySource 组合注解
@Autowired 按照类型自动装配
@Qualifier 精确指定那个beanName的使用
@Value 取值, 计算机环境变量,Jvm系统,@Value(“${test}”)
@Lookup 单例组件依赖非单例组件,非单例组件需要使用的方法
@Resource 按照名称自动转配

1.Bean

将一个实例注入到容器中, 使用Bean注解

  1. /**
  2. * default 默认按照方法名称注入, 也就是testBean1
  3. *
  4. * @return TestBean
  5. */
  6. @Bean
  7. public TestBean testBean1() {
  8. return new TestBean();
  9. }
  10. /**
  11. * 默认按照方法名称注册bean, 如果需要指定名称就是使用@Bean(value="")指定名称
  12. *
  13. * @return TestBean
  14. */
  15. @Bean(value = "testBean3")
  16. public TestBean testBean2() {
  17. return new TestBean();
  18. }
  1. // 测试代码
  2. TestBean testBean1 = applicationContext.getBean("testBean1",TestBean.class);
  3. System.out.println(testBean1);
  4. // 这里需要指定名称获取 , 如果直接使用applicationContext.getBean(TestBean.class),就会出现报错,
  5. 多个bean的使用, 不知道使用那个.

2.Primary

当一个组件有多个Bean实例注入的时候, 然后我们获取使用@Autowired 获取的时候 spring就会使用@Primary进行自动默认的获取, 也就是主要的

  1. /**
  2. * default 默认按照方法名称注入, 也就是testBean1
  3. *
  4. * @return TestBean
  5. */
  6. @Bean
  7. public TestBean testBean1() {
  8. return new TestBean();
  9. }
  10. /**
  11. * 默认按照方法名称注册bean, 如果需要指定名称就是使用@Bean(value="")指定名称
  12. * @Primary 启动, spring在不指定的情况下 , 默认获取的实例bean
  13. * @return TestBean
  14. */
  15. @Primary
  16. @Bean(value = "testBean3")
  17. public TestBean testBean2() {
  18. return new TestBean();
  19. }
  1. // 如果如果一个组件多次注入,直接使用getBean方法获取就会获取带有@Primary组件所标记的组件
  2. // 就类似@Autowired直接获取默认(@Primary)的
  3. TestBean primary_testBean = applicationContext.getBean(TestBean.class);
  4. System.out.println(primary_testBean);

3.Lazy

spring启动的时候会自动将bean组件进行注册, 并且实例化, 使用@Lazy表示只有调用该实例的时候才会实例化

  1. /**
  2. * 懒加载 , 只有用到这个实例的时候才会初始化该方法
  3. * @return
  4. */
  5. @Lazy
  6. @Bean
  7. public TestBean testBean4() {
  8. return new TestBean();
  9. }
  10. //
  1. AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TestConfiguration.class);
  2. // 如果不使用@Lazy注解, 启动就会初始化
  3. // 如果使用@Lazy注解 , 启动不会初始化

1.被实例化

image.png

2.没有实例化

image.png

4.Scope

作用域: 注册当前的组件是单例还是多例

  1. /**
  2. * 注册实例bean , 每次获取BeanA都是一个新的实例,
  3. * @return BeanA
  4. */
  5. @Bean
  6. @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  7. public BeanA beanA() {
  8. return new BeanA();
  9. }
  10. /**
  11. * 注册实例bean, 每次获取获取都是同一个实例
  12. * @return
  13. */
  14. @Bean
  15. @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
  16. public BeanB beanB() {
  17. return new BeanB();
  18. }
  1. BeanA beanA_1 = applicationContext.getBean(BeanA.class);
  2. BeanA beanA_2 = applicationContext.getBean(BeanA.class);
  3. System.out.println("beanA_1 = " + beanA_1);
  4. System.out.println("beanA_2 = " + beanA_2);
  5. BeanB beanB_1 = applicationContext.getBean(BeanB.class);
  6. BeanB beanB_2 = applicationContext.getBean(BeanB.class);
  7. System.out.println("beanB_1 = " + beanB_1);
  8. System.out.println("beanB_2 = " + beanB_2);
  9. // BeanA 每次获取的都是一个新的实例
  10. // BeanB 每次获取的都是一个同一个实例

image.png

5.Configuration

申明一个配置类

  1. @Configuration
  2. public class BeanConfiguration {
  3. }
  1. BeanConfiguration bean = applicationContext.getBean(BeanConfiguration.class);
  2. System.out.println(bean);

image.png

6.Component

Service Controller Respository 同理

  1. @Component
  2. public class TestComponent {
  3. }

image.png

7.Indexed

需要加速spring的启动速度 简单说明一下:在项目中使用了@Indexed之后,编译打包的时候会在项目中自动生成META-INT/spring.components文件。 当Spring应用上下文执行ComponentScan扫描时,META-INT/spring.components将会被CandidateComponentsIndexLoader 读取并加载,转换为CandidateComponentsIndex对象,这样的话@ComponentScan不在扫描指定的package,而是读取CandidateComponentsIndex对象,从而达到提升性能的目的

1.案例

  1. @Indexed
  2. @Component
  3. public class TestComponent {
  4. }
  1. <!-- 需要引入额外的 pom 配置 -->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context-indexer</artifactId>
  5. <version>5.0.4.RELEASE</version>
  6. </dependency>

2.注意使用点

虽然这个@Indexed注解能提升性能,但是在使用的时候也需要注意下。
假设Spring应用中存在一个包含META-INT/spring.components资源的a.jar,但是 b.jar 仅存在模式注解,那么使用@ComponentScan扫描这两个JAR中的package时,b.jar 中的模式注解不会被识别,请务必注意这样的问题。

8. Order

调整多个bean之前执行的优先级

  1. @Order(value = Ordered.LOWEST_PRECEDENCE - 1)
  2. @Component
  3. public class OrderDemo {
  4. }

9. ComponentScan

springboot 默认只会扫描当前主启动类的路径以及子路径,如果要额外增加路径就需要此注解

  1. @ComponentScan(basePackages = "com.anda.dachang.**")
  2. public class MainTest implements CommandLineRunner {
  3. @Autowired
  4. private ApplicationContext applicationContext;
  5. public static void main(String[] args) {
  6. new SpringApplicationBuilder().sources(MainTest.class).run(args);
  7. }
  8. public void run(String... args) {
  9. CompoentScanDemo compoentScanDemo = applicationContext.getBean(CompoentScanDemo.class);
  10. System.out.println(compoentScanDemo);
  11. }
  12. }

image.png

10.Conditional

按照条件注入bean

  1. public class BeanHasConditional implements Condition {
  2. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  3. String property = context.getEnvironment().getProperty("os.name");
  4. if (property.equals("Mac OS X")) {
  5. return false;
  6. }
  7. return true;
  8. }
  9. }

如果系统是Mac OS X的时候就不要注入TestBean,反之.

  1. @Bean
  2. @Conditional(BeanHasConditional.class)
  3. public TestBean testBean1() {
  4. return new TestBean();
  5. }

11.Import

1. @Import

  1. @Configuration
  2. @Import(value = {Blue.class})
  3. public class TestConfig {
  4. }

2. ImportSelector

  1. @Configuration
  2. @Import(value = {TestConfig.MyImport_Selector.class})
  3. public class TestConfig {
  4. static class MyImport_Selector implements ImportSelector {
  5. /**
  6. * @param importingClassMetadata 当前类的所有注解信息
  7. * @return
  8. */
  9. @Override
  10. public String[] selectImports(AnnotationMetadata importingClassMetadata) {
  11. return new String[]{"org.springframework.bean.Yolle"};
  12. }
  13. }
  14. }

3. ImportBeanDefinitionRegistrar

  1. @Configuration
  2. @Import(value = {TestConfig.My_ImportBeanDefinitionRegistrar.class})
  3. public class TestConfig {
  4. static class My_ImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
  5. /**
  6. * @param importingClassMetadata annotation metadata of the importing class 当前类的所有注解信息
  7. * @param registry current bean definition registry
  8. */
  9. @Override
  10. public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
  11. RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
  12. rootBeanDefinition.setBeanClass(Red.class);
  13. registry.registerBeanDefinition("redDemo", rootBeanDefinition);
  14. }
  15. }
  16. }

4.FactoryBean

  1. public class CoCoFactoryBean implements FactoryBean<CoCo> {
  2. @Override
  3. public CoCo getObject() throws Exception {
  4. return new CoCo();
  5. }
  6. @Override
  7. public Class<?> getObjectType() {
  8. return CoCo.class;
  9. }
  10. /**
  11. * 是否是单例对象
  12. *
  13. * @return
  14. */
  15. @Override
  16. public boolean isSingleton() {
  17. return false;
  18. }
  19. }
  20. @Configuration
  21. public class TestConfig {
  22. @Bean
  23. public CoCoFactoryBean coCoFactoryBean() {
  24. return new CoCoFactoryBean();
  25. }
  26. }