一、使用注解配置Bean
1、注解
在類定義、方法定義、成員變量定義前使用。其簡化<bean>標簽,功能同<bean>標簽。
格式為:
@注解標記名。
2、組件掃描
Spring可以從classpath(類路徑)下自動掃描、實例化具有特殊注解的組件。
常用注解:
(1)@Repository 一般用於數據訪問(數據訪問(持久)層組件,實現dao訪問)
(2)@Service 一般用於服務(業務層組件,處理業務邏輯,比如注入並操作dao)
(3)@Controller 一般用於控制器(控制層組件)
(4)@Component 一般用於自定義組件,把普通類實例化到spring容器中,相當於配置文件中的<bean id="" class=""/>
(5)@Scope 用於控制對象創建,默認為單例模式。
(6)@PostConstruct 用於指定init-method方法。
(7)@PreDestroy 指定destroy-method方法。
(8)@Resource 用於注入bean對象
(9)@Autowired 基本等價於 @Resource
(10)@Qualifier("XXX") 與@Autowired連用,強制按名稱匹配。
(11)@value("") Spring表達式注入。
需要在xml文件中配置自動掃描。
需要在applicationContext.xml中開啟自動掃描。 其中base-package填寫的是需要掃描的包名(可以只寫一部分,比如base-package="com",那么將會掃描以com開頭的所有包)。多個包名間用逗號(,)隔開。 <beans> <context:component-scan base-package="com.test"></context:component-scan> </beans>
對於掃描到的類,Spring默認命名為首字母小寫。
即 @Controller public class LoginController{ } 等價於 <bean id="loginController" class="XXX.LoginController"/>
3、@component
第一種形式:直接在類的前面寫@component,其會自動將類名當做id,且首字母小寫。
package com.test; import org.springframework.stereotype.Component; /** * 掃描ExampleBean組件,默認id=exampleBean * 相當於<bean id="exampleBean"></bean> * 注:id名的首字母小寫。 */ @Component public class ExampleBean { public void execute() { System.out.println("執行execute處理方法1"); } }
第二種形式:自定義id名。
package com.test; import org.springframework.stereotype.Component; /** * 相當於<bean id="test"></bean> * */ @Component("test") public class ExampleTest { public void show() { System.out.println("hello world"); } }
4、@Scope
默認為單例模式(根據同一個id,getBean獲取的都是同一個對象),可以采用@Scope("prototype") 來將其變成原型模式(根據同一個id,getBean獲取的都是不同的對象)。
package com.test; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; /** * 掃描ExampleBean組件,默認id=exampleBean * 相當於<bean id="exampleBean"></bean> * 注:id名的首字母小寫。 */ @Component @Scope("prototype") //等價於<bean scope="prototype"> public class ExampleBean { public void execute() { System.out.println("執行execute處理方法1"); } }
5、@PostConstruct
設置初始化方法。
package com.test; import javax.annotation.PostConstruct; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope("prototype") //等價於<bean scope="prototype"> public class ExampleBean { public void execute() { System.out.println("執行execute處理方法1"); } @PostConstruct //等價於<bean init-method="init"> public void init() { System.out.println("初始化"); } }
6、@PreDestroy
設置銷毀方法。
package com.test; import javax.annotation.PostConstruct; import org.springframework.stereotype.Component; @Component public class ExampleBean { public void execute() { System.out.println("執行execute處理方法1"); } @PostConstruct //等價於<bean init-method="init"> public void init() { System.out.println("初始化"); } @PreDestroy //等價於<bean destory-method="destory"> public void destory() { System.out.println("釋放資源"); } }
7、@Resource
其可以寫在變量定義前,也可以寫在setXXX方法前。@Resource默認按照ByName自動注入。@Resource有兩個重要的屬性:name和type,而Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以,如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不制定name也不制定type屬性,這時將通過反射機制使用byName自動注入策略。
其導入包:import javax.annotation.Resource;
注:
使用注解時,若@Resource注解寫在變量定義前,那么setXXX方法可以不寫。
但若是在xml文件中采用<bean>標簽的set注入,需要實現setXXX方法。
@Resource裝配順序:
step1:如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常。
step2:如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。
step3:如果指定了type,則從上下文中找到類似匹配的唯一bean進行裝配,找不到或是找到多個,都會拋出異常。
step4:如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配。
private Computer computer; @Resource private Phone phone; //插入類型為Phone的對象 @Resource //注入bean對象 public void setComputer(Computer computer) { this.computer = computer; }
8、@Autowired
基本等價於 @Resource。@Autowired注解是按照類型(byType)裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它的required屬性為false。如果我們想使用按照名稱(byName)來裝配,可以結合@Qualifier注解一起使用
其導入包:import org.springframework.beans.factory.annotation.Autowired;
private Computer computer; @Autowired private Phone phone; //插入類型為Phone的對象 @Autowired //注入bean對象 public void setComputer(Computer computer) { this.computer = computer; }
9、@Resource與@Autowired的區別
@Resource的作用相當於@Autowired,只不過@Autowired默認按照byType自動注入。@Resource默認按 byName自動注入
注:
構造器注入時,只能使用@Autowired。
Set注入時,可以使用@Autowired或者@Resource(推薦)。
容器中存在多個同類型的對象時,若@Autowired放在setXX方法前,那么只依據類型(ByType)去匹配。若想使@Autowired 按照byName匹配,需與@Qualifier("")連用。
@Autowired @Qualifier("computer") private Computer computer;
@Resource放在setXXX方法前,會先依據XXX(默認ByName)去匹配,可以設置是否按照byName或者byType匹配。
@Resource(name="phone") //等價於 @Resource,根據byName匹配。