spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。
spring从两个角度实现自动化装配:
组件扫描:Spring会自动发现应用上下文中所创建的bean
自动装配:Spring自动满足bean之间的依赖。
package com.soundsystem;
/**
* @author shanyangyang
* @date 2020/5/3
*/
public interface CompactDisc {
void play();
}
package com.soundsystem;
import org.springframework.stereotype.Component;
/**
* @author shanyangyang
* @date 2020/5/3
*/
@Component
public class SgtPeppers implements CompactDisc {
private String title = "Sgt. Pepper's Lonely Hearts CLub Band";
private String artist = "The Beatles";
@Override public void play() {
}
}
spring开启组件扫描
java配置方式
@ComponentScan public class CDPlayConfig { }
XML方式启用组件扫描
<!--开启组件扫描-->
<context:component-scan base-package="com.ysy" />
profile
配置profile bean
profile bean:可以做到根据环境决定创建哪个bean和不创建哪个bean。
@Configuration
@Profile("dev")
public class DevelopmentProfileConfig {
}
它会告诉spring这个配置类中的bean只有在 dev profile激活时才创建。spring3.2之后,profile也可以配置在方法上。
在XML中配置profile
<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"
profile="dev">
激活profile
spring在确定哪个profile处于激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default。如果active的值设置了,才采用active的值,否则会查找default的值。
有多种方法设置这两个属性:
1、作为DispatcherServlet的初始化参数
2、作为Web应用的上下文参数
3、作为JNDI目录
4、作为环境变量
5、作为JVM的系统属性
6、在集成测试类上,使用@ActiveProfiles注解设置
在web应用的web上下文中设置默认的profile
<!--为上下文设置默认的profile -->
<context-param>
<context-name>spring.profile.default</context-name>
<param-value>dev</param-value>
</context-param>
<!--为servlet设置默认的profile -->
<servlet>
<init-param>
<param-name>spring.profile.default</param-name>
<param-value>dev</param-value>
</init-param>
</servlet>
条件化的bean
@Condition注解,它可以用到带有@Bean注解的方法上。如果给定的条件计算结果为true,就会创建这个bean,否则的话,这个bean会被忽视。
处理自动装配的歧义性
不过,仅有一个bean匹配所需的结果时,自动装配才是有效的。如果不仅一个bean能够匹配结果的话,这种歧义性会阻碍Spring自动装配属性、构造器参数或方法参数。
报错:NoUniqueBeanDefinitionException
解决方法:
1、标示首选的bean
@Primary:可以与@Component组合用在组件扫描的bean上,也可以与@Bean组合用在java配置的bean声明中。
2、限定自动装配的bean
@Qualifier:注解是使用限定符的主要方式。它可以与@Autowired和@Inject协同使用,在注入的时候指定想要注入进去的是哪个bean
我们可以自定义限定符,达到精细化控制的目标。
bean的作用域
默认情况下,Spring应用上下文中所有bean都是作为单例的形式创建的。
如何将会话或者请求作用域的bean注入到单例bean中?
@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.INTERFACES)
指定proxyMode为ScopedProxyMode.INTERFACES后,spring不会讲实例的bean注入到单例bean中,而是会注入一个bean的代理。
作用域代理能够延迟注入请求和会话作用的bean