@Configuration 和 @Bean
@Configuration 用于定义配置类,可替换 xml
配置文件,被注解的类内部包含有一个或多个被 @Bean 注解的方法,这些方法将会被AnnotationConfigApplicationContext
或 AnnotationConfigWebApplicationContext
类进行扫描,并用于构建 bean 定义,初始化 Spring 容器。
@Bean 是一个方法级别上的注解,主要用在 @Configuration 注解的类里,也可以用在 @Component 注解的类里。添加的bean的id为方法名。
简单使用:
@Configuration
public class ConfigDemo {
@Bean
public User user1(){
User user = new User("heigou",18);
return user;
}
}
@SpringBootApplication
public class Demo3Application {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Demo3Application.class, args);
ConfigDemo configDemo = run.getBean(ConfigDemo.class);
User user1 = configDemo.user1();
System.out.println(user1); //User(name=heigou, age=18)
}
}
@Bean 默认是单例模式:
@SpringBootApplication
public class Demo3Application {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Demo3Application.class, args);
ConfigDemo configDemo = run.getBean(ConfigDemo.class);
User user1 = configDemo.user1();
User user2 = configDemo.user1();
System.out.println(user1 == user2); //true
}
}
可以通过 @Configuration(proxyBeanMethods = false)
将 @Bean 方法被调用时返回的组件都是新创建的:
@Configuration(proxyBeanMethods = false)
public class ConfigDemo {
@Bean
public User user1(){
User user = new User("heigou",18);
return user;
}
}
@SpringBootApplication
public class Demo3Application {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Demo3Application.class, args);
ConfigDemo configDemo = run.getBean(ConfigDemo.class);
User user1 = configDemo.user1();
User user2 = configDemo.user1();
System.out.println(user1 == user2); //false
}
}
Spring Boot 在2.2.0版本(依赖于Spring 5.2.0)起就把它的所有的自动配置类的此属性改为了false,即 @Configuration(proxyBeanMethods = false)
,提高Spring启动速度。
- FULL模式:
@Configuration(proxyBeanMethods = true)
,保证每个@Bean方法被调用多少次返回的组件都是单实例的。配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用 FULL 模式。 - LITE模式:
@Configuration(proxyBeanMethods = false)
,每个@Bean方法被调用多少次返回的组件都是新创建的,配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断。
@Component
@Component用于标注在类上,标注了该注解的类将会被Spring扫描并注入到Spring IOC容器中。
添加了该注解的类,会在Spring启动阶段被扫描并注入到IOC中。具体流程如下:
Spring启动 -> 触发 ClassPathBeanDefinitionScanner
类 doScan
方法 -> 根据配置路径读取 class 的信息 -> 判断类是否包含 @Component 注解 -> 将包含注解的类根据其信息创建成 BeanDefinition
-> 注册到Spring中。
@Controller, @Service, @Repository 是 @Component 的细化,这三个注解比 @Component 带有更多的语义,它们分别对应了控制层、服务层、持久层的类。
注意:@Mapper 是 mybatis 中的注解。
@ComponentScan
@ComponentScan主要就是定义扫描的路径从中找出标识了标识了@Controller,@Service,@Repository,@Component注解的类自动装配到spring的bean容器中。
如果你的其他包都在使用了 @SpringBootApplication 注解的 mainApp 所在的包及其下级包,则你什么都不用做,SpringBoot会自动帮你把其他包都扫描了。
如果你有一些bean所在的包,不在mainApp的包及其下级包,那么你需要手动加上@ComponentScan注解并指定那个bean所在的包。
@Import
给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名:
@Import({User.class, DBHelper.class})
@Configuration
public class MyConfig {
}
@Conditional
条件装配:满足Conditional指定的条件,则进行组件注入。
@ImportResource
原生配置文件引入:
======================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"
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>
@ImportResource("classpath:beans.xml")
public class MyConfig {}
======================测试=================
boolean haha = run.containsBean("haha");
boolean hehe = run.containsBean("hehe");
System.out.println("haha:"+haha);//true
System.out.println("hehe:"+hehe);//true