SpringBoot常用的底层注解

@Configuration

在聊@Configuration之前,先说一下spring中声明bean的方法。一开始是使用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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="haha" class="com.atguigu.boot.bean.User">
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>

    <bean id="hehe" class="com.atguigu.boot.bean.Pet">
        <property name="name" value="tomcat"></property>
    </bean>
</beans>

使用bean标签,id是该bean的id,是唯一的标识,class是要声明为bean对象的类,property是bean对象里面的属性。通过这种方式的确可以声明一个bean,但是却十分的麻烦,在创建容器的时候,还要读取该xml文件。于是可以用另外一种简单的方式来替代配置文件声明bean的方式,使用@Configuration注解,使用该注解等同于使用xml配置文件,下面是注解使用的方式:

@Configuration
public class Myconfig {

    @Bean
    public User user1() {
        return new User();
    }

@Configuration作用在类上面,表示该类是一个配置类,等同于之前的xml配置文件;@Bean注解作用在方法上面,方法的名字user1就是要声明bean的名字,方法的返回类型User就是Bean的类型。可以看到,通过注解配置的方式是完全等同于使用xml文件的方式的,只不过之前spring读取的是xml文件,现在读取的是该配置类。

然后运行程序,在启动类中测试,可以发现User 类型的bean 已经存在于ioc容器当中了:

@SpringBootApplication
public class SpringbootApplicationTest {
    public static void main(String[] args) {
        //run 就是ioc容器
        ConfigurableApplicationContext run = SpringApplication.run(SpringbootApplicationTest.class, args);
        Object user1 = run.getBean("user1");
        System.out.println(user1);
     
    }
}

打印的结果:
在这里插入图片描述

proxyBeanMethods属性

需要注意的是@Configuration里面有一个属性,一般不写表示默认为true,该属性的意思为是否要代理用户去拿spring容器里面的对象,该属性为proxyBeanMethods,贴图如下:
在这里插入图片描述
这里我们就知道了其实用@Configuration标识的类默认是一个代理类:
在这里插入图片描述
如果将属性proxyBeanMethods设置为false,则不会是代理类,也就不会从spring容器里面取东西,设置如下:
在这里插入图片描述
打印Myconfig类:
在这里插入图片描述
该属性的意义就是让bean保持单例。每次要创建一个bean都会从容器中去寻找,如果有该bean了,则直接获取,没有的话再进行创建。

使用场景:对象之间的依赖引用。
下图是配置类,里面声明了两个bean,并且Pet对象作为了User类里面的一个属性。

@Configuration(proxyBeanMethods = false)
public class Myconfig {

    @Bean
    public User user1() {
        User zhangsan = new User();
        zhangsan.setPet(pet1());
        return zhangsan;
    }

    @Bean
    public Pet pet1() {
        return new Pet();
    }
}

这表示已经在容器中创建了两个对象bean,现在我不想用容器里面的bean,只需要把属性proxyBeanMethods设置为false即可,测试的代码如下:

@SpringBootApplication
public class SpringbootApplicationTest {
    public static void main(String[] args) {

        //run 就是ioc容器
        ConfigurableApplicationContext run = SpringApplication.run(SpringbootApplicationTest.class, args);
        //容器中的user1
        User user = run.getBean("user1", User.class);
        //容器中的pet1
        Pet pet = run.getBean("pet1", Pet.class);
        //如果设置@Configuration(proxyBeanMethods = false),则生成的对象和容器中对象不是一个。
        System.out.println(user.getPet() == pet);
    }
}

打印的结果为false:
在这里插入图片描述

@Import

该注解的意思顾名思义,就是直接向spring容器中导入bean。导入的是类型是class:
在这里插入图片描述
现在想要直接向spring容器中导入User类型的一个对象,方法如下:

@Configuration(proxyBeanMethods = false)
@Import({User.class})
public class Myconfig {
    @Bean
    public User user1() {
        User zhangsan = new User("zhangsan", 18); 
        return zhangsan;
    }
   
}

测试的代码:

@SpringBootApplication
public class SpringbootApplicationTest {
    public static void main(String[] args) {
        //run 就是ioc容器
        ConfigurableApplicationContext run = SpringApplication.run(SpringbootApplicationTest.class, args);

        //获取所有类型为User的bean
        String[] beanNamesForType = run.getBeanNamesForType(User.class);
        for (String s : beanNamesForType) {
            System.out.println(s);
        }
    }
}

打印结果如下:

一个是全限定为名的bean,也就是使用@Import注解导入的,另一个是声明的bean。

@Conditional

该注解的意思是要进行条件判断,只要满足该条件的话才执行某些方法,下面是@Conditional所有的注解:
在这里插入图片描述
举一个例子,下面的意思如果容器中不存在Pet类型的bean,再创建user1 的bean对象:

@Configuration
public class Myconfig {

    @Bean
    public Pet pet1() {
        return new Pet("tomcat");
    }

    @Bean
    @ConditionalOnMissingBean(Pet.class)
    public User user1() {
        User zhangsan = new User("zhangsan", 18);
        zhangsan.setPet(pet1());
        return zhangsan;
    }
}

测试代码:

@SpringBootApplication
public class SpringbootApplicationTest {
    public static void main(String[] args) {

        //run 就是ioc容器
        ConfigurableApplicationContext run = SpringApplication.run(SpringbootApplicationTest.class, args);
        //判断容器中是否存在user1
        boolean user1 = run.containsBean("user1");
        System.out.println(user1);
    }
}

因为容器中存在Pet类型的对象,所以spring不会创建user1,最终打印的结果为false。
该注解不仅可以作用在方法上,作用在类上也是可以的,表示如果满足某个条件在执行类里面的所有方法。使用的场景一般是多个对象之间的组合,当满足或者不足某个对象的时候再创建另外一个对象。

@ConfigurationProperties

该注解的作用是读取配置文件中的值,并与类中的属性进行绑定、赋值。
现在声明一个yml文件:
在这里插入图片描述
然后声明一个实体类:

@Component
//下面代码的含义是读取配置文件前缀为“mycar”的内容并将内容赋值给Car对象,但前提是必须将对象放到ioc容器中才能生效。
@ConfigurationProperties(prefix = "mycar")
@Data
public class Car {

    private String brand;
    private Integer price;

}

配置文件中的brand和price是Car类中的两个属性;当使用@ConfigurationProperties的时候,会把配置文件中的值给该类的属性赋上。但是该类一定要加上@Component注解,因为如果想要让该操作生效,一定要把该类作为spring管理的对象才可以。

测试代码:

@RestController
public class ControllerTest {

    @Autowired
    Car car;

    @RequestMapping("/test")
    private Car test() {
        return car;
    }
}

测试结果:
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值