1. 装配Bean
三种装配机制:
- 在XML中进行显式配置;
- 在Java中进行显式配置;
- 隐式的bean发现机制和自动装配。
1.1 自动化装配Bean
最强大的是Spring自动化装配,从以下两个方面实现自动化装配:
- 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
- 自动装配(autowiring):Spring自动满足bean之间的依赖。
组件扫描启动需要配置:
@Configuration
@ComponentScan
public class CDPlayerConfig {}
默认扫描配置类所在包及其所有子包带有@Component注解的类。
1.2 为bean命名
Spring默认bean名称为类名的第一个字母小写的名称,可进行自命名,如下:
@Component("lonelyHeartsClub")
public class SgtPeppers {
}
另一种命名方案:@Named("abc"),可自行查阅。
1.3 设置组件扫描基础包
根据字符串
@Configuration
@ComponentScan("soundsystem")
public class CDPlayerConfig {}
或者
@Configuration
@ComponentScan(basePackages="soundsystem")
public class CDPlayerConfig {}
针对扫描多个基础包的情况如下:
@Configuration
@ComponentScan(basePackages={"soundsystem", "video"})
public class CDPlayerConfig {}
根据类型
根据类所在的包作为扫描基础包
@Configuration
@ComponentScan(basePackages={CDPlayer.class, DVDPlayer.class})
public class CDPlayerConfig {}
2. 通过为bean添加注解实现自动装配
通过@Autowired注解进行自动装配,
required属性:默认为true,不存在bean会抛出异常。
也可使用@Inject.
3. 通过Java代码装配bean
将第三方库中的组件装配到自己的应用中。
3.1 创建配置类
@Configuration
public class CDPlayerConfig {
@Bean
public CompactDisc sgtPeppers() {
return new SgtPeppers();
}
}
默认情况下,bean的ID与带有@Bean注解的方法名是一样的,可自定义命名,如下:
@Configuration
public class CDPlayerConfig {
@Bean(name="lonelyHeartsClubBand")
public CompactDisc sgtPeppers() {
return new SgtPeppers();
}
}
3.2 借助JavaConfig实现注入
第一种:直接引用创建bean的方法
@Bean
public CDPlayer cdPlayer() {
return new CDPlayer(sgtPeppers());
}
因为sgtPeppers()方法上添加了@Bean注解,Spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。
第二种:直接通过方法参数:
@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc) {
return new CDPlayer(sgtPeppers());
}
4. 环境与profile
通过@Profile注解指定某个bean属于哪一个profile,该注解能用于类上,也能用于方法上。
4.1 激活profile
确定profile的激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default。如果设置了spring.profiles.active属性的话,那么它的值就会用来确定profile的激活。但如果没有设置spring.profiles.active属性的话,那么spring将查找spring.profiles.default的值。
5. 条件化bean
通过@Conditional注解实现,如下:
@Bean
@Conditional(MagicExistsCondition.class)
public MagicBean magicBean() {
return new MagicBean();
}
MagicExistsCondition的代码如下:
public class MagicExistsCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
return env.containsProperty("magic");
}
}
6. 处理自动装配的歧义性
6.1 标示首选的bean
直接在bean上加@Primary注解,来避免歧义性。
@Bean
@Primary
public MagicBean magicBean() {
return new MagicBean();
}
6.2 限定自动装配的bean
使用@Qualifier注解限定符来缩小范围,达到限制条件锁位为一个bean的目的。
@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
如果没有指定bean限定符的情况下,所有的bean都会给定一个默认的限定符,它的值和bean ID相同。
6.3 创建自定义限定符
@Component
@Qualifier("cold")
public class IceCream implements Dessert {...}
6.4 使用自定义的限定符注解
通过创建自定义注解,使用@Qualifier注解来标注,它们就具有了@Qualifier注解的特性,它们本身实际上就成为了限定符注解。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold {
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy {
}
使用的时候如下:
@Component
@Cold
@Fruity
public void Popsicle implements Dessert {...}
装配如下:
@Autowired
@Cold
@Creamy
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
7. bean的作用域
默认情况下,所有bean都是以单例的形式进行创建的,Spring一共定义了四种作用域,如下:
- 单例(Singleton):只创建一个实例。
- 原型(Prototype):每次注入都会创建一个新的bean实例。
- 会话(Session):在web应用中,为每个会话创建一个bean实例。
- 请求(Request):为每个请求创建一个bean实例。
@Component
@Scopt(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad {...}
网友评论