Spring註解標籤詳解@Autowired @Qualifier等 @Slf4j
@Slf4j @Slf4j註解實現日誌輸出
自己寫日誌的時候,肯定需要:
private final Logger logger = LoggerFactory.getLogger(LoggerTest.class);
1
每次寫新的類,就需要重新寫logger
有簡單的方式,就是使用@Slf4j註解
首先是在pom中引入:
<!--可以引入日誌 @Slf4j註解-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
1
2
3
4
5
然後在類上寫上@Slf4j註解
在方法中直接使用
如果註解@Slf4j注入後找不到變數log,需要IDEA安裝lombok外掛,
File → settings → Plugins
如圖
安裝完成後重啟即可
package cn.chenhaoxiang;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import lombok.extern.slf4j.XSlf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Created with IntelliJ IDEA.
* User: 陳浩翔.
* Date: 2018/1/8.
* Time: 下午 8:05.
* Explain:日誌測試
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class LoggerTest {
private final Logger logger = LoggerFactory.getLogger(LoggerTest.class);
/**
* 傳統方式實現日誌
*/
@Test
public void test1(){
logger.debug("debug");//預設日誌級別為info
logger.info("info");
logger.error("error");
logger.warn("warn");
}
/**
* Slf4j註解方式實現日誌
*/
@Test
public void test2(){
log.debug("debug");//預設日誌級別為info
log.info("info");
log.error("error");
log.warn("warn");
}
}
@Autowired
spring2.1中允許使用者通過@Autowired註解對Bean的屬性變數.屬性Setter方法以及建構函式進行標註,配合AutowiredAnnotationBeanProcessor完成Bean的自動配置。使用@Autowired註釋進行byType注入。
在applicationContext.xml中加入:
<!-- 該 BeanPostProcessor 將自動對標註 @Autowired 的 Bean 進行注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
通過 @Autowired的使用來消除 set ,get方法。
- @Autowired
- private UserDao userdao;
這樣就可以刪除set ,get方法和spring中的相關配製了。
- <bean id="userDao" class="..."/>
- <bean id="userService" class="...">
- <property name="userDao">
- <ref bean="userDao"/>
- </property>
- </bean>
通過@Autowired屬的Setter方法給父類中的屬性注入值。
- public void setDataSource(DataSource dataSource)
- {
- super.setDataSource(dataSource);
- }
@Autowired(required = false)
當不能確定 Spring 容器中一定擁有某個類的 Bean 時,可以在需要自動注入該類 Bean 的地方可以使用 @Autowired(required = false) ,這等於告訴 Spring:在找不到匹配 Bean 時也不報錯。
當然,一般情況下,使用 @Autowired 的地方都是需要注入 Bean 的,使用了自動注入而又允許不注入的情況一般僅會在開發期或測試期碰到(如為了快速啟動 Spring 容器,僅引入一些模組的 Spring 配置檔案),所以 @Autowired(required = false) 會很少用到。
@Qualifier
使用@Autowired註釋進行byType注入,如果需要byName(byName就是通過id去標識)注入,增加@Qualifier註釋。一般在候選Bean數目不為1時應該加@Qualifier註釋。
在預設情況下使用 @Autowired 註釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將丟擲
BeanCreationException 異常,並指出必須至少擁有一個匹配的 Bean。
和找不到一個型別匹配 Bean 相反的一個錯誤是:如果 Spring 容器中擁有多個候選 Bean,Spring 容器在啟動時也會丟擲 BeanCreationException 異常。
Spring 允許我們通過 @Qualifier 註釋指定注入 Bean 的名稱,這樣歧義就消除了,可以通過下面的方法解決異常:
- public void setOffice(@Qualifier("office")Office office)
- {
- this.office =office;
- }
也可以直接注入到屬性:
- private Office office;
@Qualifier(“office”)中的office是Bean的名稱,所以@Autowired和@Qualifier結合使用時,自動注入的策略就從byType轉變成byName了。
@Autowired可以對成員變數、方法以及建構函式進行註釋,而@Qualifier的標註物件是成員變數、方法入參、建構函式入參。正是由於註釋物件的不同,所以Spring不將 @Autowired和@Qualifier統一成一個註釋類。
@Qualifier 只能和@Autowired 結合使用,是對@Autowired有益的補充。
一般來講,@Qualifier對方法簽名中入參進行註釋會降低程式碼的可讀性,而對成員變數註釋則相對好一些。
@Resource
Spring不但支援自己定義的@Autowired註解,還支援幾個由JSR-250規範定義的註解,它們分別是@Resource、@PostConstruct以及@PreDestroy。
@Resource的作用相當於@Autowired,只不過@Autowired按byType自動注入,而@Resource預設按 byName自動注入罷了。@Resource有兩個屬性是比較重要的,分是name和type,Spring將@Resource註解的name屬性解析為bean的名字,而type屬性則解析為bean的型別。所以如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不指定name也不指定type屬性,這時將通過反射機制使用byName自動注入策略。
@Resource裝配順序
1. 如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則丟擲異常
2. 如果指定了name,則從上下文中查詢名稱(id)匹配的bean進行裝配,找不到則丟擲異常
3. 如果指定了type,則從上下文中找到型別匹配的唯一bean進行裝配,找不到或者找到多個,都會丟擲異常
4. 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始型別進行匹配,如果匹配則自動裝配;
@Component、@Repository、@Service、@Controller
Spring 2.5 中除了提供 @Component 註釋外,還定義了幾個擁有特殊語義的註釋,它們分別是:@Repository、@Service 和 @Controller。
在目前的 Spring 版本中,這 3 個註釋和 @Component 是等效的,但是從註釋類的命名上,很容易看出這 3 個註釋分別和持久層、業務層和控制層(Web 層)相對應。
雖然目前這3 個註釋和 @Component 相比沒有什麼新意,但 Spring 將在以後的版本中為它們新增特殊的功能。
所以,如果 Web 應用程式採用了經典的三層分層結構的話,最好在持久層、業務層和控制層分別採用上述註解對分層中的類進行註釋。
@Service用於標註業務層元件
@Controller用於標註控制層元件(如struts中的action)
@Repository用於標註資料訪問元件,即DAO元件
@Component泛指元件,當元件不好歸類的時候,我們可以使用這個註解進行標註。
- public class VentorServiceImpl implements iVentorService {
- }
- public class VentorDaoImpl implements iVentorDao {
- }
在一個稍大的專案中,如果元件採用xml的bean定義來配置,顯然會增加配置檔案的體積,查詢以及維護起來也不太方便。
Spring2.5為我們引入了元件自動掃描機制,他在類路徑下尋找標註了上述註解的類,並把這些類納入進spring容器中管理。
它的作用和在xml檔案中使用bean節點配置元件時一樣的。要使用自動掃描機制,我們需要開啟以下配置資訊:
<?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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config /> <context:component-scan base-package=”com.iteedu.spring”> </beans>
annotation-config是對標記了@Required、@Autowired、@PostConstruct、@PreDestroy、@Resource、@WebServiceRef、@EJB、@PersistenceContext、@PersistenceUnit等註解的類進行對應的操作使註解生效。
base-package為需要掃描的包(含所有子包),負責掃描那些類有註解。
可以使用以下方式指定初始化方法和銷燬方法:
- public void init() {
- }
- public void destory() {
- }
from: http://www.voidcn.com/blog/u013144121/article/p-2933655.html