[Spring]Annotation-based container configuration_AnotationBasis_01

基于注解的容器配置

首先使用注解和xml配置,本质上没有好坏之分,只有适合不适合之分。如果你觉得哪个顺手就用哪个,或者都用。


首先要使用anotation-config 需要在xml中配置

<context:annotation-config/>:该句自动的注册AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, RequiredAnnotationBeanPostProcessor处理器。

当然如果直接配置了

<context:component-scan base-package="com.javaconfig.domain"/> 那么也就是默认配置了<context:annotation-config/>,所以只需要定义这个,没必要定义上面的那个。


@Required

注解适用于bean属性的setter方法并且它指示,受影响的bean属性必须在配置时被填充在XML配置文件中,否则容器将抛出BeanInitializationException

如下例子:

被注入类定义

public class Instrument {
	public void play() {
		System.out.println("play instrument.");
	}
}

注入类

public class Player {
	
	private Instrument instrument;

	public void play() {
		instrument.play();
	}


	public Instrument getInstrument() {
		return instrument;
	}
	@Required
	public void setInstrument(Instrument instrument) {
		this.instrument = instrument;
	}

}


xml 配置

<bean id="instrument" class="com.domain.Instrument"/>
	<bean id="player" class="com.domain.Player" >
		<!-- <property name="instrument" ref="instrument"></property> -->
	</bean>

注意player里面的property是被注释掉的,如果所以这个时候会报错,取消注释恢复正常



@Autowired

默认按类型注入,如果存在0个或者多个待选类型,则会报错。能够被应用于fields,constructor,setter method.

对于被@Autowired标注的对象甚至可以是private类型。

@Component
public class Football {
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "football";
	}
}


public class FootballPlayer {
	@Autowired
	private Football football;
	public void play(){
		System.out.println("footballPlayer is playing " + football);
	}
}


可以直接注入到私有的football field里,甚至不需要setter method。

可以同时注入多个依赖

public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao; }
// ...
}


可以为某些集合数组类型提供依赖注入,将所有可能待选bean注入其中,比如

public class MovieRecommender { @Autowired
private MovieCatalog[] movieCatalogs;
// ...
}

这将把容器内注册的所有MovieCatalog注入其中,如果注入的类型是map,则会自动按照 name:object 注入 name即是bean的名字

@Autowired可选属性有required,每个类只能有一个required = true ,可以存在多个required = false 当遇到多个可以选择方案时候,spring 容器采用贪心策略注入。



@Primary

因为@Autowired 会导致个可能注入bean发生,这个时候可以用@Primary来申明 某个待注入bean 为最优方法

@Configuration
public class MovieConfiguration {
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... } @Bean
public MovieCatalog secondMovieCatalog() { ... }
// ...
}

这个时候如果某个类需要注入MovieCatalog 需要注入bean的时候 会首先选择@Primary标注的

public class MovieRecommender { @Autowired
private MovieCatalog movieCatalog;
// ...
}

这个时候注入的就是firstMovieCatalog



@Qulifier

当你需要指定特定的某一个bean,成为待注入对象的时候 你可以使用@Qualifier来标注

public class MovieRecommender {
@Autowired
    @Qualifier("main")
private MovieCatalog movieCatalog;
// ...
}

public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(@Qualifier("main")MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao; }
// ...
}

这个时候autowired 会注入main所限定名称的bean

你可以按照自己的需要定制属于自己的@Qulifier

比如

@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
    String value();
}

public class MovieRecommender {
@Autowired
    @Genre("Action")
private MovieCatalog actionCatalog; private MovieCatalog comedyCatalog;
@Autowired
public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) { this.comedyCatalog = comedyCatalog;
}
// ...
}

效果等同于@Qulifier

一般情况下你并不需要指定那么详细,你只需要指定Anotaion的名字即可

@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Offline {
}

这个时候可以通过@Offline注入对应的bean

public class MovieRecommender {
@Autowired
@Offline
private MovieCatalog offlineCatalog;
// ...
}

甚至可以使用枚举来作为参数限定

@Target({ElementType.FIELD, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MovieQualifier {
    String genre();
    Format format();
}


 public enum Format { VHS, DVD, BLURAY
}

public class MovieRecommender {
}
@Autowired
@MovieQualifier(format=Format.VHS, genre="Action") private MovieCatalog actionVhsCatalog;
@Autowired
@MovieQualifier(format=Format.VHS, genre="Comedy") private MovieCatalog comedyVhsCatalog;
@Autowired
@MovieQualifier(format=Format.DVD, genre="Action") private MovieCatalog actionDvdCatalog;
@Autowired
@MovieQualifier(format=Format.BLURAY, genre="Comedy") private MovieCatalog comedyBluRayCatalog;
// ...}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值