@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注解
/**
* default 默认按照方法名称注入, 也就是testBean1
*
* @return TestBean
*/
@Bean
public TestBean testBean1() {
return new TestBean();
}
/**
* 默认按照方法名称注册bean, 如果需要指定名称就是使用@Bean(value="")指定名称
*
* @return TestBean
*/
@Bean(value = "testBean3")
public TestBean testBean2() {
return new TestBean();
}
// 测试代码
TestBean testBean1 = applicationContext.getBean("testBean1",TestBean.class);
System.out.println(testBean1);
// 这里需要指定名称获取 , 如果直接使用applicationContext.getBean(TestBean.class),就会出现报错,
多个bean的使用, 不知道使用那个.
2.Primary
当一个组件有多个Bean实例注入的时候, 然后我们获取使用@Autowired 获取的时候 spring就会使用@Primary进行自动默认的获取, 也就是主要的
/**
* default 默认按照方法名称注入, 也就是testBean1
*
* @return TestBean
*/
@Bean
public TestBean testBean1() {
return new TestBean();
}
/**
* 默认按照方法名称注册bean, 如果需要指定名称就是使用@Bean(value="")指定名称
* @Primary 启动, spring在不指定的情况下 , 默认获取的实例bean
* @return TestBean
*/
@Primary
@Bean(value = "testBean3")
public TestBean testBean2() {
return new TestBean();
}
// 如果如果一个组件多次注入,直接使用getBean方法获取就会获取带有@Primary组件所标记的组件
// 就类似@Autowired直接获取默认(@Primary)的
TestBean primary_testBean = applicationContext.getBean(TestBean.class);
System.out.println(primary_testBean);
3.Lazy
spring启动的时候会自动将bean组件进行注册, 并且实例化, 使用@Lazy表示只有调用该实例的时候才会实例化
/**
* 懒加载 , 只有用到这个实例的时候才会初始化该方法
* @return
*/
@Lazy
@Bean
public TestBean testBean4() {
return new TestBean();
}
//
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(TestConfiguration.class);
// 如果不使用@Lazy注解, 启动就会初始化
// 如果使用@Lazy注解 , 启动不会初始化
1.被实例化
2.没有实例化
4.Scope
作用域: 注册当前的组件是单例还是多例
/**
* 注册实例bean , 每次获取BeanA都是一个新的实例,
* @return BeanA
*/
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public BeanA beanA() {
return new BeanA();
}
/**
* 注册实例bean, 每次获取获取都是同一个实例
* @return
*/
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public BeanB beanB() {
return new BeanB();
}
BeanA beanA_1 = applicationContext.getBean(BeanA.class);
BeanA beanA_2 = applicationContext.getBean(BeanA.class);
System.out.println("beanA_1 = " + beanA_1);
System.out.println("beanA_2 = " + beanA_2);
BeanB beanB_1 = applicationContext.getBean(BeanB.class);
BeanB beanB_2 = applicationContext.getBean(BeanB.class);
System.out.println("beanB_1 = " + beanB_1);
System.out.println("beanB_2 = " + beanB_2);
// BeanA 每次获取的都是一个新的实例
// BeanB 每次获取的都是一个同一个实例
5.Configuration
申明一个配置类
@Configuration
public class BeanConfiguration {
}
BeanConfiguration bean = applicationContext.getBean(BeanConfiguration.class);
System.out.println(bean);
6.Component
Service Controller Respository 同理
@Component
public class TestComponent {
}
7.Indexed
需要加速spring的启动速度 简单说明一下:在项目中使用了@Indexed之后,编译打包的时候会在项目中自动生成META-INT/spring.components文件。 当Spring应用上下文执行ComponentScan扫描时,META-INT/spring.components将会被CandidateComponentsIndexLoader 读取并加载,转换为CandidateComponentsIndex对象,这样的话@ComponentScan不在扫描指定的package,而是读取CandidateComponentsIndex对象,从而达到提升性能的目的
1.案例
@Indexed
@Component
public class TestComponent {
}
<!-- 需要引入额外的 pom 配置 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
2.注意使用点
虽然这个@Indexed注解能提升性能,但是在使用的时候也需要注意下。
假设Spring应用中存在一个包含META-INT/spring.components资源的a.jar,但是 b.jar 仅存在模式注解,那么使用@ComponentScan扫描这两个JAR中的package时,b.jar 中的模式注解不会被识别,请务必注意这样的问题。
8. Order
调整多个bean之前执行的优先级
@Order(value = Ordered.LOWEST_PRECEDENCE - 1)
@Component
public class OrderDemo {
}
9. ComponentScan
springboot 默认只会扫描当前主启动类的路径以及子路径,如果要额外增加路径就需要此注解
@ComponentScan(basePackages = "com.anda.dachang.**")
public class MainTest implements CommandLineRunner {
@Autowired
private ApplicationContext applicationContext;
public static void main(String[] args) {
new SpringApplicationBuilder().sources(MainTest.class).run(args);
}
public void run(String... args) {
CompoentScanDemo compoentScanDemo = applicationContext.getBean(CompoentScanDemo.class);
System.out.println(compoentScanDemo);
}
}
10.Conditional
按照条件注入bean
public class BeanHasConditional implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String property = context.getEnvironment().getProperty("os.name");
if (property.equals("Mac OS X")) {
return false;
}
return true;
}
}
如果系统是Mac OS X的时候就不要注入TestBean,反之.
@Bean
@Conditional(BeanHasConditional.class)
public TestBean testBean1() {
return new TestBean();
}
11.Import
1. @Import
@Configuration
@Import(value = {Blue.class})
public class TestConfig {
}
2. ImportSelector
@Configuration
@Import(value = {TestConfig.MyImport_Selector.class})
public class TestConfig {
static class MyImport_Selector implements ImportSelector {
/**
* @param importingClassMetadata 当前类的所有注解信息
* @return
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"org.springframework.bean.Yolle"};
}
}
}
3. ImportBeanDefinitionRegistrar
@Configuration
@Import(value = {TestConfig.My_ImportBeanDefinitionRegistrar.class})
public class TestConfig {
static class My_ImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param importingClassMetadata annotation metadata of the importing class 当前类的所有注解信息
* @param registry current bean definition registry
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClass(Red.class);
registry.registerBeanDefinition("redDemo", rootBeanDefinition);
}
}
}
4.FactoryBean
public class CoCoFactoryBean implements FactoryBean<CoCo> {
@Override
public CoCo getObject() throws Exception {
return new CoCo();
}
@Override
public Class<?> getObjectType() {
return CoCo.class;
}
/**
* 是否是单例对象
*
* @return
*/
@Override
public boolean isSingleton() {
return false;
}
}
@Configuration
public class TestConfig {
@Bean
public CoCoFactoryBean coCoFactoryBean() {
return new CoCoFactoryBean();
}
}
�