日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Spring框架之基于注解的容器配置

默認(rèn)情況下,Spring容器中的注解配置沒(méi)有被打開(kāi)。因此,在我們使用基于注解的配置之前,我們需要在Spring配置文件中啟用它。因此,如果你想在你的Spring應(yīng)用程序中使用任何注解,請(qǐng)考慮以下配置文件。

@Required注解是方法級(jí)注解,適用于Bean的setter方法。這個(gè)注解簡(jiǎn)單地表明setter方法必須在配置時(shí)被配置為具有依賴(lài)注入的值。

@Component

@Component
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Required
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}

屬性movieFinder必須存在,若注入時(shí)為null,會(huì)拋NullPointerException異常。

@Autowired

我們可以使用@Autowired來(lái)標(biāo)記Spring將要解析和注入的依賴(lài)關(guān)系。我們可以在構(gòu)造函數(shù)、Setter或字段注入中使用這個(gè)注解。

構(gòu)造函數(shù)注入

class Car {
private Engine engine;

@Autowired
Car(Engine engine) {
this.engine = engine;
}
}

Setter 注入

class Car {
private Engine engine;
@Autowired
void setEngine(Engine engine) {
this.engine = engine;
}
}

字段注入

class Car {
@Autowired
private Engine engine;
}

@Primary

當(dāng)有多個(gè)相同類(lèi)型的Bean時(shí),使用@Primary來(lái)給一個(gè)Bean更高的優(yōu)先權(quán)。

為什么需要@Primary?在某些情況下,我們需要注冊(cè)超過(guò)一個(gè)相同類(lèi)型的Bean。在這個(gè)例子中,我們有mySQLConnection()和oracleConnection()的Connection類(lèi)型的bean。

@Configuration
public class Config {
@Bean
public Connection mySQLConnection() {
return new MySQLConnection();
}
@Bean
public Connection oracleConnection() {
return new OracleConnection();
}
}

如果我們運(yùn)行該應(yīng)用程序,Spring會(huì)拋出NoUniqueBeanDefinitionException。為了訪(fǎng)問(wèn)具有相同類(lèi)型的Bean,我們通常使用@Qualifier("beanName")注解,和@Autowired一起應(yīng)用。在我們的案例中,我們?cè)谂渲秒A段配置Bean,所以@Qualifier不能在這里應(yīng)用。關(guān)于@Qualifier會(huì)在本章后面講到。

為了解決這個(gè)問(wèn)題,Spring提供了@Primary注解。下面的例子展示了如何在一個(gè)Spring應(yīng)用程序中使用@Primary注解。
@Primary注解可用于任何直接或間接用@Component注解的類(lèi)或用@Bean注解的工廠(chǎng)方法。在這個(gè)例子中,我們將使用@Primary注解和@Component注解。

package com.demo.spring.primary;
public interface MessageService {
public void sendMsg();
}
package com.demo.spring.primary;
import org.springframework.stereotype.Component;
@Component
public class FacebookMessageService implements MessageService {
@Override
public void sendMsg() {
System.out.println("FacebookMessageService implementation here");
}
}
package com.demo.spring.primary;
import org.springframework.stereotype.Component;
@Component
public class EmailMessageService implements MessageService {
@Override
public void sendMsg() {
System.out.println("EmailMessageService Implementation here");
}
}
package com.demo.spring.primary;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Primary
@Component
public class TwitterMessageService implements MessageService {
@Override
public void sendMsg() {
System.out.println("TwitterMessageService Implementation here");
}
}

請(qǐng)注意,在上述TwitterMessageService類(lèi)中,我們添加了@Primary與@Component注解。

package com.demo.spring.primary;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.demo.spring.primary")
public class AppConfig {

}
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MessageService messageService = context.getBean(MessageService.class);
messageService.sendMsg();
context.close();
}
}

Output:

TwitterMessageService Implementation here

@Qualifier

當(dāng)我們創(chuàng)建了多個(gè)相同類(lèi)型的Bean,但只想將其中一個(gè)與某個(gè)屬性關(guān)聯(lián)??梢允褂聾Qualifier注解和@Autowired注解來(lái)控制。
@Qualifier用于解決模糊的依賴(lài)關(guān)系,也就是說(shuō),它幫助@Autowired注解選擇其中一個(gè)依賴(lài)關(guān)系。如果一個(gè)接口有多種實(shí)現(xiàn),那么我們可以在運(yùn)行時(shí)使用@Qualifier來(lái)選擇所需的實(shí)現(xiàn)。

public interface MessageService {
public void sendMsg(String message);
}
public class EmailService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
public class TwitterService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
public class SMSService implements MessageService{
public void sendMsg(String message) {
System.out.println(message);
}
}
public interface MessageProcessor {
public void processMsg(String message);
}
public class MessageProcessorImpl implements MessageProcessor {
private MessageService messageService;
// setter based DI
@Autowired
@Qualifier("TwitterService")
public void setMessageService(MessageService messageService) {
this.messageService = messageService;
}
// constructor based DI
@Autowired
public MessageProcessorImpl(@Qualifier("TwitterService") MessageService messageService) {
this.messageService = messageService;
}
public void processMsg(String message) {
messageService.sendMsg(message);
}
}
@Configuration
@ComponentScan("com.demo.springframework.di")
public class AppConfiguration {
@Bean(name="emailService")
public MessageService emailService(){
return new EmailService();
}
@Bean(name="twitterService")
public MessageService twitterService(){
return new TwitterService();
}
@Bean(name="smsService")
public MessageService smsService(){
return new SMSService();
}
@Bean
public MessageProcessor messageProcessor(){
return new MessageProcessorImpl(twitterService());
}
}
public class TestApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);
MessageProcessor userService = applicationContext.getBean(MessageProcessor.class);
userService.processMsg("twitter message sending ");
}
}

Output:

twitter message sending 

@Resource

Spring支持通過(guò)@Resource(javax.annotation.Resource)方式注入,可以在字段或setter方法上加該注解,@Resource有一個(gè)name屬性,如果不指定name,默認(rèn)就是字段或setter方法名稱(chēng)。

public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}

@Value

該注解可用于向Spring管理的Bean中的字段注入值,它可以應(yīng)用于字段或構(gòu)造函數(shù)/方法參數(shù)級(jí)別。

我們需要一個(gè)屬性文件來(lái)定義我們想用@Value注解注入的值。因此,我們首先需要在我們的配置類(lèi)中定義一個(gè)@PropertySource--帶有屬性文件名。

value.from.file=Value got from the file
priority=high
listOfValues=A,B,C

注意:Spring Boot默認(rèn)配置了一個(gè)PropertySourcesPlaceholderConfigurer的Bean,它將從application.properties和application.yml文件中獲取屬性。

@Value("${value.from.file}")
private String valueFromFile;

有時(shí),我們需要注入一堆值。將它們定義為屬性文件中單個(gè)屬性用逗號(hào)分隔的值,或定義為系統(tǒng)屬性并注入一個(gè)數(shù)組。例如listOfValues中定義了逗號(hào)分隔的值,所以數(shù)組的值將是["A","B", "C"]。

@Value("${listOfValues}")
private String[] valuesArray;

使用SpEL表達(dá)式

使用SpEL表達(dá)式獲取配置文件中priority的值。

@Value("#{systemProperties['priority']}")
private String spelValue;

如果在property文件中沒(méi)有定義屬性,就會(huì)報(bào)nullvalue異常。為了防止這種情況,我們可以在SpEL表達(dá)式中提供一個(gè)默認(rèn)值。如果屬性沒(méi)有定義,我們就為該字段設(shè)置默認(rèn)值。

@Value("#{systemProperties['unknown'] ?: 'some default'}")
private String spelSomeDefault;

我們也可以用其它bean的屬性值:

@Value("#{someBean.someValue}")
private Integer someBeanValue;

從屬性配置中獲取List列表:

@Value("#{'${listOfValues}'.split(',')}")
private List valuesList;

把@Value注入到Map加入propeties文件中有如下key:

valuesMap={key1: '1', key2: '2', key3: '3'}

注意,Map中的值必須是單引號(hào)。

@Value("#{${valuesMap}}")
private Map valuesMap;

如果要獲取map中指定的key:

@Value("#{${valuesMap}.key1}")
private Integer valuesMapKey1;

如果不確定Map中是否包含key,我們可以使用一個(gè)安全的表達(dá)式,使其不會(huì)拋出異常,并且設(shè)置值為null:

@Value("#{${valuesMap}['unknownKey']}")
private Integer unknownMapKey;

為屬性設(shè)置默認(rèn)值:

@Value("#{${unknownMap : {key1: '1', key2: '2'}}}")
private Map unknownMap;

@Value("#{${valuesMap}['unknownKey'] ?: 5}")
private Integer unknownMapKeyWithDefaultValue;

注入前過(guò)濾不需要的值:

@Value("#{${valuesMap}.?[value>'1']}")
private Map valuesMapFiltered;

與構(gòu)造函數(shù)一起注入

@Component
@PropertySource("classpath:application.properties")
public class PriorityProvider {

private String priority;

@Autowired
public PriorityProvider(@Value("${priority:normal}") String priority) {
this.priority = priority;
}

// standard getter
}

注意:默認(rèn)配置文件是application.properties或application.yaml則不需要@PropertySource注解。

與Setter一起注入

@Component
@PropertySource("classpath:values.properties")
public class CollectionProvider {
private List values = new ArrayList<>();
@Autowired
public void setValues(@Value("#{'${listOfValues}'.split(',')}") List values) {
this.values.addAll(values);
}
// standard getter
}

@PostConstruct and @PreDestroy

我們可以自定義Bean的創(chuàng)建和銷(xiāo)毀附動(dòng)作。我們可以通過(guò)實(shí)現(xiàn)InitializingBean和DisposableBean接口來(lái)實(shí)現(xiàn)它。我們也可以用@PostConstruct和@PreDestroy注解來(lái)實(shí)現(xiàn)。

@PostConstruct

Spring只調(diào)用一次用@PostConstruct注釋的方法,就在Bean屬性初始化之后。請(qǐng)記住,即使沒(méi)有任何東西需要初始化,這些方法也會(huì)運(yùn)行。帶有@PostConstruct注釋的方法不能是靜態(tài)的。

@Component
public class DbInit {
@Autowired
private UserRepository userRepository;
@PostConstruct
private void postConstruct() {
User admin = new User("admin", "admin password");
User normalUser = new User("user", "user password");
userRepository.save(admin, normalUser);
}
}

@PreDestroy

帶有@PreDestroy注解的方法只運(yùn)行一次,就在Spring將我們的Bean從容器中移除之前。帶有@PreDestroy注解的方法不能是靜態(tài)的。

@Component
public class UserRepository {
private DbConnection dbConnection;
@PreDestroy
public void preDestroy() {
dbConnection.close();
}
}

網(wǎng)站標(biāo)題:Spring框架之基于注解的容器配置
轉(zhuǎn)載來(lái)源:http://www.dlmjj.cn/article/dppdcph.html