Spring經常使用註解簡析

1. Autowired
  自動裝配,其做用是爲了消除代碼Java代碼裏面的getter/setter與bean屬性中的property。固然,getter看我的需求,若是私有屬性須要對外提供的話,應當予以保留。
  @Autowired默認按類型匹配的方式,在容器查找匹配的Bean,當且僅一個匹配的Bean時,Spring將其注入@Autowired標註的變量中。
  當Spring發現@Autowired註解時,將自動在代碼上下文中找到和其匹配(默認是類型匹配)的Bean,並自動注入到相應的地方去。
  @Autowired(required=false) 這時找不到bean,Spring容器再也不拋出異常而是認爲bean爲null。html

2. Qualifier(指定注入Bean的名稱)
  若是容器中一個以上匹配的Bean,則能夠經過@Qualifier註解限定Bean的名稱,看下面的例子:java

<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">
    
    <context:component-scan base-package="com.spring" />
    
    <!-- Autowired註解配合Qualifier註解 -->
    <bean id="animal" class="com.spring.model.Animal" />
    <bean id="donkey" class="com.spring.service.impl.Donkey" />
    <bean id="monkey" class="com.spring.service.impl.Monkey" />
    
</beans> 

這時xml文件中配置了兩個bean(donkey,monkey), 若是Autowired未指定具體類名時,Animal接口會加載兩個bean, 但接口只有一個實現類,就會報錯。出現這種狀況一般兩種解決辦法:
  (1) 在配置文件中刪除其中一個實現類,Spring會自動去base-package下尋找Animal接口的實現類,發現Animal接口只有一個實現類,便會直接引用這個實現類。
  (2) 實現類就是有多個該怎麼辦?此時可使用@Qualifier註解來指定Bean的名稱,以下:spring

public class CarFactory {
    @Autowired
    @Qualifier("monkey")
    private Animal animal;
 
    public String toString(){
        return car.getAnimalName();
    }
} 

此處會注入名爲"monkey"的Bean。安全

3. Resource
@Resource註解與@Autowired註解做用很是類似,其裝配順序以下:
  (1) @Resource後面沒有任何內容,默認經過name屬性去匹配bean,找不到再按type去匹配
  (2) 指定了name或者type則根據指定的類型去匹配bean
  (3) 指定了name和type則根據指定的name和type去匹配bean,任何一個不匹配都將報錯異步

@Autowired和@Resource兩個註解的區別:
  (1) @Autowired默認按照byType方式進行bean匹配,@Resource默認按照byName方式進行bean匹配
  (2) @Autowired是Spring的註解,@Resource是J2EE的註解,這個看一下導入註解的時候這兩個註解的包名就一清二楚了
Spring屬於第三方的,J2EE是Java本身的東西,所以,建議使用@Resource註解,以減小代碼和Spring之間的耦合。ui

4. Component
@Component是全部受Spring 管理組件的通用形式,@Component註解能夠放在類的頭上,@Component不推薦使用。prototype

5. Controller
@Controller對應表現層的Bean,也就是Action,例如:線程

@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User>{
   ……
}

  使用@Controller註解標識UserAction以後,就表示要把UserAction交給Spring容器管理,在Spring容器中會存在一個名字爲"userAction"的action,這個名字是根據UserAction類名來取的。注意:若是@Controller不指定其value【@Controller】,則默認的bean名字爲這個類的類名首字母小寫,若是指定value【@Controller(value="UserAction")】或者【@Controller("UserAction")】,則使用value做爲bean的名字。
  這裏的UserAction還使用了@Scope註解,@Scope("prototype")表示將Action的範圍聲明爲原型,能夠利用容器的scope="prototype"來保證每個請求有一個單獨的Action來處理,避免struts中Action的線程安全問題。spring 默認scope 是單例模式(scope="singleton"),這樣只會建立一個Action對象,每次訪問都是同一Action對象,數據不安全,struts2 是要求每次次訪問都對應不一樣的Action,scope="prototype" 能夠保證當請求的時候都建立一個Action對象。component

6. Service
@Service對應的是業務層Bean,例如:xml

@Service("userService")
public class UserServiceImpl implements UserService {
  ………
}

   @Service("userService")註解是告訴Spring,當Spring要建立UserServiceImpl的的實例時,bean的名字必須叫作"userService",這樣當Action須要使用UserServiceImpl的的實例時,就能夠由Spring建立好的"userService",而後注入給Action:在Action只須要聲明一個名字叫"userService"的變量來接收由Spring注入的"userService"便可,具體代碼以下:

@Resource(name = "userService")
private UserService userService;

 注意:

  在Action聲明的"userService"變量的類型必須是"UserServiceImpl"或者是其父類"UserService",不然因爲類型不一致而沒法注入.

  因爲Action中的聲明的"userService"變量使用了@Resource註解去標註,而且指明瞭其name = "userService",這就等於告訴Spring,說我Action要實例化一個"userService",你Spring快點幫我實例化好,而後給我,
當Spring看到userService變量上的@Resource的註解時,根據其指明的name屬性能夠知道,Action中須要用到一個UserServiceImpl的實例,此時Spring就會把本身建立好的名字叫作"userService"的UserServiceImpl的實例注入給Action中的"userService"變量,幫助Action完成userService的實例化,這樣在Action中就不用經過"UserService userService = new UserServiceImpl();"這種最原始的方式去實例化userService了。
  若是沒有Spring,那麼當Action須要使用UserServiceImpl時,必須經過"UserService userService = new UserServiceImpl();"主動去建立實例對象,但使用了Spring以後,Action要使用UserServiceImpl時,建立UserServiceImpl實例已經交給Spring來作了,Spring把建立好的UserServiceImpl實例給Action,Action拿到就能夠直接用了。
Action由原來的主動建立UserServiceImpl實例後就能夠立刻使用,變成了被動等待由Spring建立好UserServiceImpl實例以後再注入給Action,Action纔可以使用。這說明Action對"UserServiceImpl"類的「控制權」已經被「反轉」了,原來主動權在本身手上,本身要使用"UserServiceImpl"類的實例,本身主動去new一個出來立刻就可使用了,但如今本身不能主動去new "UserServiceImpl"類的實例,new "UserServiceImpl"類的實例的權力已經被Spring拿走了,只有Spring纔可以new "UserServiceImpl"類的實例,而Action只能等Spring建立好"UserServiceImpl"類的實例後,再「懇求」Spring把建立好的"UserServiceImpl"類的實例給它,這樣它纔可以使用"UserServiceImpl",這就是Spring核心思想「控制反轉」,也叫「依賴注入」,「依賴注入」也很好理解,Action須要使用UserServiceImpl幹活,那麼就是對UserServiceImpl產生了依賴,Spring把Acion須要依賴的UserServiceImpl注入(也就是「給」)給Action,這就是所謂的「依賴注入」。對Action而言,Action依賴什麼東西,就請求Spring注入給它,對Spring而言,Action須要什麼,Spring就主動注入給它。

7. Repository

@Repository對應數據訪問層Bean ,例如:

@Repository(value="userDao")
public class UserDaoImpl extends BaseDaoImpl<User> {
   ………
}

@Repository(value="userDao")註解是告訴Spring,讓Spring建立一個名字叫"userDao"的UserDaoImpl實例。

當Service須要使用Spring建立的名字叫"userDao"的UserDaoImpl實例時,就可使用@Resource(name = "userDao")註解告訴Spring,Spring把建立好的userDao注入給Service便可。以下:

@Resource(name = "userDao")
private BaseDao<User> userDao;

8. 其餘註解:@Configuration: 把一個類做爲一個IoC容器,它的某個方法頭上若是註冊了@Bean,就會做爲這個Spring容器中的Bean。@Scope:註解做用域@Lazy(true): 表示延遲初始化@Component: 泛指組件,當組件很差歸類的時候,咱們可使用這個註解進行標註。@Scope: 用於指定scope做用域的(用在類上)@PostConstruct: 用於指定初始化方法(用在方法上)@PreDestory: 用於指定銷燬方法(用在方法上)@DependsOn:定義Bean初始化及銷燬時的順序@Primary:自動裝配時當出現多個Bean候選者時,被註解爲@Primary的Bean將做爲首選者,不然將拋出異常@Resource:默認按名稱裝配,當找不到與名稱匹配的bean纔會按類型裝配。@PostConstruct: 初始化註解@PreDestroy : 摧毀註解,默認單例,啓動就加載@Async: 異步方法調用

相關文章
相關標籤/搜索