ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringBoot的@Configuration扫盲

2021-07-21 21:58:45  阅读:190  来源: 互联网

标签:SpringBoot AppConfig public 扫盲 Bean MyBean Configuration class


@Configuration注解标识的类中声明了1个或者多个@Bean方法,Spring容器可以使用这些方法来注入Bean,比如:

@Configuration
public class AppConfig {
  //这个方法就向Spring容器注入了一个类型是MyBean名字是myBean的Bean
  @Bean
  public MyBean myBean() {
     // instantiate, configure and return bean ...
  }
}


@Configuration类一般是由AnnotationConfigApplicationContext或者它的web变种AnnotationConfigWebApplicationContext来处理的,比如:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
//这是configuration类
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
// use myBean ...


也可以用以XML方式引入,就跟引入普通的Bean是一样的:

<beans>
  <context:annotation-config/>
  <!--也可以这样加载configuration类-->
  <bean class="com.acme.AppConfig"/>
</beans>


上例中,为了启用ConfigurationClassPostProcessor和其他的注解相关的Post Processor来处理@Configuration,需要添加context:annotation-config/。

组件扫描的方式使用

@Configuration上面添加了@Component元注解,因此, @Configuration是支持组件扫描的(一般要添加context:component-scan/ ) ,它跟其他普通的Component一样也支持@Autowired/@Inject,如果@Configuration的类有一个构造函数,也支持构造函数自动注入,比如:

@Configuration
public class AppConfig {
  private final SomeBean someBean;
  //构造函数注入
  public AppConfig(SomeBean someBean) {
    this.someBean = someBean;
  }
  //注入另一个bean
  @Autowired
  private AnotherBean1 anotherBean1;
  
  //注入另一个bean
  @Resource
  private AnotherBean2 anotherBean2;
  // @Bean definition using "SomeBean"
}


@Configuration 类不仅可以被扫描到,它自己也可以配置@ComponentScan注解去做组件扫描。

@Configuration
//做组件扫描
@ComponentScan("com.acme.app.services")
public class AppConfig {
  // various @Bean definitions ...
}


在@Configuration中使用property
使用Environment获取property


可以把org.springframework.core.env.Environment注入到@Configuration里面来获取property值,比如可以使用@Autowired注入:

@Configuration
public class AppConfig {
  //注入Environment 
  @Autowired 
  Environment env;
  @Bean
  public MyBean myBean() {
    MyBean myBean = new MyBean();
    myBean.setName(env.getProperty("bean.name"));
    return myBean;
  }
}


通过Environment获取的property可以存在于多个"property source" 对象中,@Configuration类本身也可以使用@PropertySource来提供"property source":

@Configuration
//引入property文件
@PropertySource("classpath:/com/acme/app.properties")
public class AppConfig {
  @Inject 
  Environment env;
  @Bean
  public MyBean myBean() {
    return new MyBean(env.getProperty("bean.name"));
  }
}


使用@Value注解获取property

@Configuration
@PropertySource("classpath:/com/acme/app.properties")
public class AppConfig {
  @Value("${bean.name}") 
  String beanName;
  @Bean
  public MyBean myBean() {
    return new MyBean(beanName);
  }
}


这种方式经常和PropertySourcesPlaceholderConfigurer一起使用,PropertySourcesPlaceholderConfigurer可以通过配置context:property-placeholder/来自动启用,也可以在@Configuration类中用@Bean明确来启用。

注意,只有当你需要自定义占位符等场景才需要用@Bean来注册PropertySourcesPlaceholderConfigurer,如果ApplicationContext中没有明确注册PropertySourcesPlaceholderConfigurer,Spring容器会在Environment中自动注册一个默认的property解析器。

使用@EnableConfigurationProperties

这种方式可以引入@ConfigurationProperties标识的注解类,比如:

@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnBean(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {
    ...
}
@ConfigurationProperties(prefix = MybatisProperties.MYBATIS_PREFIX)
public class MybatisProperties {
    ...
}


组合@Configuration类
使用@Import注解

可以使用@Import注解组合多个@Configuration类,就跟在xml中使用 引入别的配置文件一样。因为@Configuration对象是被Spring容器当成Bean来管理的,被引入的Configuration类也可以被容器管理和注入,比如可以用构造函数注入的方式:

//这是一个@Configuration类
@Configuration
public class DatabaseConfig {
  @Bean
  public DataSource dataSource() {
  // instantiate, configure and return DataSource
  }
}
//这里可以引用上面的配置类
@Configuration
@Import(DatabaseConfig.class)
public class AppConfig {
  private final DatabaseConfig dataConfig;
  public AppConfig(DatabaseConfig dataConfig) {
    this.dataConfig = dataConfig;
  }
  @Bean
  public MyBean myBean() {
    // reference the dataSource() bean method
    return new MyBean(dataConfig.dataSource());
  }
}


现在只需要在容器中注册AppConfig就可以同时注册AppConfig和DatabaseConfig了,比如:

new AnnotationConfigApplicationContext(AppConfig.class);


使用@Profile注解

@Configuration可以跟@Profile一起使用,说明只有在给定的profile下@Configuration 才能生效:

@Profile("development")
@Configuration
public class EmbeddedDatabaseConfig {
  @Bean
  public DataSource dataSource() {
    // instantiate, configure and return embedded DataSource
  }
}
@Profile("production")
@Configuration
public class ProductionDatabaseConfig {
  @Bean
  public DataSource dataSource() {
    // instantiate, configure and return production DataSource
  }
}


此外还可以在@Bean 方法级别上设置profile,比如:

@Configuration
public class ProfileDatabaseConfig {
  @Bean("dataSource")
  @Profile("development")
  public DataSource embeddedDatabase() { ... }
  @Bean("dataSource")
  @Profile("production")
  public DataSource productionDatabase() { ... }
}


使用@ImportResource注解引入Spring的xml配置

@Configuration类可以在xml中像普通的bean那样定义,同时也可以在@Configuration类中使用@ImportResource引入xml配置文件,被引入的xml中定义的bean也可以被注入,比如:

@Configuration
@ImportResource("classpath:/com/acme/database-config.xml")
public class AppConfig {
  @Inject DataSource dataSource; // from XML
  @Bean
  public MyBean myBean() {
    // inject the XML-defined dataSource bean
    return new MyBean(this.dataSource);
  }
}


虽然可以,但是不推荐,相当于是一种兼容xml的做法。

嵌套的@Configuration类

@Configuration类可以内嵌在别的@Configuration类当中(比如mybatis-spring-boot-starter的MybatisAutoConfiguration):

@Configuration
public class AppConfig {
  @Inject DataSource dataSource;
  @Bean
  public MyBean myBean() {
    return new MyBean(dataSource);
  }
  @Configuration
  static class DatabaseConfig {
    @Bean
    DataSource dataSource() {
      return new EmbeddedDatabaseBuilder().build();
    }
  }
}


只需要注册AppConfig就可以同时把AppConfig和DatabaseConfig一块注入到容器中,内嵌的DatabaseConfig会被自动注册,这种方式就避免了使用@Import。
注意这种内嵌的@Configuration类的方式也可以和 @Profile一起使用来提供同一个bean的多种实现。

配置延迟初始化

默认情况下,@Bean方法是在容器启动时立即加载的,@Configuration可以和@Lazy一起使用,表明所有的@Bean 方法都是延迟初始化的,当然@Lazy也可以标注在单个@Bean方法上。

@Configuration类如何做测试

Spring的Test框架提供了@ContextConfiguration注解,他可以接受

// @Configuration类:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {AppConfig.class, DatabaseConfig.class})
public class MyTests {
  @Autowired MyBean myBean;
  @Autowired DataSource dataSource;
  @Test
  public void test() {
  // assertions against myBean ...
  }
}


使用@Enable启用Spring的内置的特性

Spring的一些特性比如异步方法调用、任务调度、注解驱动的事务管理、甚至是SpringMVC都可以通过配置@Configuration来启用,详细信息可以参考@EnableAsync, @EnableScheduling, @EnableTransactionManagement, @EnableAspectJAutoProxy @EnableWebMvc。

@Configuration类的一些限制

@Configuration类必须是class,不能是工厂方法返回的实例,允许运行时增强。
@Configuration类一定不能是final的。
@Configuration类一定不能是local的(不能在方法内部定义)
@Configuration类的内嵌的配置类必须是static的。
@Bean方法不能创建配置类,@Bean方法定义的bean只是普通的Bean,即使有@Configuration注解也不会被容器使用。

标签:SpringBoot,AppConfig,public,扫盲,Bean,MyBean,Configuration,class
来源: https://blog.csdn.net/weixin_46535927/article/details/118977089

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有