Spring Boot常见注解

1、@Configuration

@Configuration 用于定义配置类,可替换XML配置文件,被注解的类内部包含一个或多个@Bean注解方法。配置类可以被AnnotationConfigApplicationContext或者AnnotationConfigWebApplicationContext 进行加载。用于构建bean定义以及初始化Spring容器。

(1)配置类里面使用@Bean注解在方法上给容器注册组件(默认是单例)

@Configuration  //告诉Spring Boot这是一个配置类==配置文件,配置类也是一个组件
public class MyConfig {
    
    @Bean  //给容器中添加组件:方法名作为组件的id,返回类型就是组件类型,返回值就是组件在容器中的实例
    public Book book1(){
        return new Book("三国演义","罗贯中",30,new Date());
    }
    
    @Bean("book")  //此时组件的id为@Bean("")的括号里指定的名称
    public Book book2(){
        return new Book("水浒传","施耐庵",35,new Date());
    }
}

(2)返回IOC容器,查看容器中的组件

//返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class,args);

//查看容器里的所有组件名称
String[]names = run.getBeanDefinitionNames();
for(String name:names){
System.out.println(name);
}

//获取容器中的组件
Book book1 = run.getBean("book2",Book.class);   //"book"指定容器中存在的组件名称

可以发现,容器中已经存在book1和book两个组件。
在这里插入图片描述
注意:

@Configuration有个属性proxyBeanMeathods(代理Bean的方法),该属性有两种取值:Full 全模式和Lite 轻量级模式,默认为Full全模式。

Full(proxyBeanMethods = true) :proxyBeanMethods参数设置为true时即为:Full 全模式。 该模式下注入容器中的同一个组件无论被取出多少次都是同一个bean实例,即单实例对象,在该模式下SpringBoot每次启动都会判断检查容器中是否存在该组件。
Lite(proxyBeanMethods = false) :proxyBeanMethods参数设置为false时即为:Lite 轻量级模式。该模式下注入容器中的同一个组件无论被取出多少次都是不同的bean实例,即多实例对象,在该模式下SpringBoot每次启动会跳过检查容器中是否存在该组件。

什么时候用Full全模式,什么时候用Lite轻量级模式?

当在你的同一个Configuration配置类中,注入到容器中的bean实例之间有依赖关系时,建议使用Full全模式;
当在你的同一个Configuration配置类中,注入到容器中的bean实例之间没有依赖关系时,建议使用Lite轻量级模式,以提高springboot的启动速度和性能。

总结
@Configuation等价于<Beans></Beans>
@Bean 等价于<Bean></Bean>
@ComponentScan等价于<context:component-scan base-package="com.dxz.demo"/>
@Component 等价于<Bean></Bean>

@Bean 与 @Component比较:
● 两个注解的结果是相同的,bean都会被添加到Spring上下文中。
● @Component 标注的是类,允许通过自动扫描发现;@Bean需要在配置类@Configuation中使用。
● @Component类使用的方法或字段时不会使用CGLIB增强;而在@Configuration类中使用方法或字段时则使用CGLIB创建代理对象。

2、@import

@import的参数value接收一个Class数组,通过快速导入的方式实现把实例(以全类名作为id)注册入spring的IOC容器中。
注意:@Import只能用在类上;@Import注解可以用于导入第三方包。

(1)@Import的三种用法
● 直接填class数组方式
● ImportSelector方式【重点】
● ImportBeanDefinitionRegistrar方式

①第一种用法:直接填class数组

@Import({ 类名.class , 类名.class... })
public class Test {

}

import的bean都将加入到spring的IOC容器中,这些在容器中bean名称是该类的全类名 ,比如com.newstar.类名。

②第二种用法:ImportSelector方式
ImportSelector是一个接口,必须要创建一个类来继承实现它。

public class MyImportSelector implements ImportSelector {
//实现接口中方法
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.test.importdemo.Test"};  //一定要写全类名!!!
    }
}

参数说明:
●参数: AnnotationMetadata表示当前被@Import注解给标注的所有注解信息(固定写法)。
●返回值:要导入到容器中的组件全类名。

③第三种用法:ImportBeanDefinitionRegistrar方式
同样是一个接口,类似于第二种ImportSelector用法,只不过这种用法比用于自定义化注册。

public class MyImport implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        //指定bean定义信息(包括bean的类型、作用域...)
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class);    //指定bean的类型
        //注册一个bean指定bean名字(id)
        beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition);     //自定义bean的名字
    }
}

参数说明:
●第一个参数:annotationMetadata 和之前的ImportSelector参数一样都是表示当前被@Import注解给标注的所有注解信息(固定写法)。
●第二个参数表示用于注册定义一个bean(固定写法)。

示例

//第二种方式
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"newstar.springboot.entity.Book1"};  //一定要写全类名!!!
    }
}

//第三种方式
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        //指定bean定义信息(包括bean的类型、作用域...)
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Book2.class);    //指定bean的类型
        //注册一个bean指定bean名字(id)
        beanDefinitionRegistry.registerBeanDefinition("book123",rootBeanDefinition);     //自定义bean的名字
    }
}

//第一种方式直接填充class
@Import({Book.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class Test {
	@Bean
    public Book booktest(){
    	return new Book();
        }
}

//打印IOC容器中组件名称
public class AnnotationTestDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(Test.class);  //这里的参数代表要做操作的类
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames){
            System.out.println(name);
        }
    }
}

结果如下:
在这里插入图片描述
类全部注册进IOC容器中。

3、@Conditional

条件装配:@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,需要注入的Bean满足给定条件才可以注入到Spring IOC容器中

(1)标注在类上:@Conditional标注在类上就决定了一批bean是否注入。

//如果WindowsCondition的实现方法返回true,则该类下的所有bean全部注入容器,否则全不注入。  
@Conditional({WindowsCondition.class})
@Configuration
public class BeanConfig {
 
    @Bean(name = "bill")
    public Person person1(){
        return new Person("Bill Gates",62);
    }
 
    @Bean("linus")
    public Person person2(){
        return new Person("Linus",48);
    }
}

(2)标注在方法上:@Conditional标注在方法上只能控制一个bean实例是否注入。

@Configuration
public class BeanConfig {
 
    //如果WindowsCondition的实现方法返回true,则注入这个bean    
    @Conditional({WindowsCondition.class})
    @Bean(name = "bill")
    public Person person1(){
        return new Person("Bill Gates",62);
    }
 
    //如果LinuxCondition的实现方法返回true,则注入这个bean
    @Conditional({LinuxCondition.class})
    @Bean("linus")
    public Person person2(){
        return new Person("Linus",48);
    }
}

@Conditional有许多适用于不同场景的扩展注解如下:

1.class条件注解
  @ConditionalOnClass:某个class位于类路径上,才会实例化一个Bean@ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean2.Bean条件注解
  @ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
  @ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。

3.属性条件注解
  @ConditionalOnProperty:当指定的属性有指定的值时进行实例化。

4.Resource条件注解
  @ConditionalOnResource:当类路径下有指定的资源时触发实例化。

5.web条件注解
  @ConditionalOnNotWebApplication:不是web应用,才会实例化一个Bean@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
  
6.表达式条件注解
  @ConditionalOnExpression:基于SpEL表达式的条件判断,当表达式为true的时候,才会实例化一个Bean@ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
  @ConditionalOnJndi:在JNDI存在的条件下触发实例化。
  @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。

4、@ImportResource()

@ImportResource注解用于导入Spring的配置文件,让配置文件里面的内容生效(就是以前写的springmvc.xml、applicationContext.xml或者自定义的xxx.xml)。

Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,不能自动识别;如果想让Spring的配置文件生效加载进来,就必须使用@ImportResource注解。

@ImportResource注解标注在一个配置类上或者主程序入口类上均可
(1)配置文件beans.xml

//配置文件beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="book4" class="newstar.springboot.entity.Book4">
        <property name="name" value="西游记"/>
        <property name="author" value="吴承恩"/>
    </bean>
</beans>

(2)配置文件导入生效

//方式一:配置类中导入
@ImportResource("classpath:beans.xml")  //beans.xml放在src/resources/目录下
@Configuration  //告诉Spring Boot这是一个配置类==配置文件
public class MyConfig {
}

//方式二:在主程序入口类中导入
@ImportResource("classpath:beans.xml")
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
    ...
    }

5、@ConfigurationProperties

Spring boot 应用中,当使用注解方式定义一个 bean 时,同时可以利用 @ConfigurationProperties 导入外部属性填充到这个 bean 的实例。

在配置文件 src/main/resources/application.properties 做以下配置:

section1.name=Tom
section2.name=Jerry
section3.name=Dog

(1)方式1 : @ConfigurationProperties + @Component 注解到 bean 定义类上

// 将类定义为一个bean的注解,比如 @Component,@Service,@Controller,@Repository
// 或者 @Configuration
@Component
// 表示使用配置文件中前缀为 section1 的属性的值初始化该bean定义产生的的bean实例的同名属性
// 在使用时这个定义产生的bean时,其属性 name 会是 Tom
@ConfigurationProperties(prefix = "section1")
public class Bean1 {
	
    private String name;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

(2)方式2 : @ConfigurationProperties + @Bean 注解在配置类的 bean 定义方法上

// 这是一个一般java类,POJO,没有任何注解
public class Bean2 {


    private String name;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


// 声明为为一个配置类
@configuration
public class Application {
	
    @Bean
    // 使用配置文件中前缀为section2的属性的值初始化这里bean定义所产生的bean实例的同名属性,
    // 在使用时这个定义产生的bean时,其属性 name 会是 Jerry
    @ConfigurationProperties(prefix = "section2")
    public Bean2 bean2() {
	    // 注意,这里的 Bean2 是上面所示的一个POJO类,没有任何注解
        return new Bean2();
    }
}

(3)方式3 : @ConfigurationProperties 注解到普通类然后通过 @EnableConfigurationProperties 定义为 bean

// 该注解声明如果该类被定义为一个bean,则对应的bean实例的属性值将来自配置文件中前缀为
// section3的同名属性。但是这个注解本身并不会导致该类被作为一个bean注册
@ConfigurationProperties(prefix = "section3")
public class Bean3 {

    private String name;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


@SpringBootApplication
// 该注解会将类Bean3作为一个bean定义注册到bean容器,而类Bean3上的注解
// @ConfigurationProperties(prefix = "section3")会导致目标bean
// 实例的属性值使用配置文件中前缀为section3的同名属性值来填充,也就是目标
// bean的属性name的值会是Dog
@EnableConfigurationProperties({Bean3.class})
public class Application {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值