1.Spring注解
Spring除了默認的使用xml配置文件的方式實現配置之外,也支持使用注解的方式實現配置,這種方式效率更高,配置信息更清晰,修改更方便,推薦使用。
所謂注解就是給程序看的提示信息,很多時候都是用來做為輕量級配置的方式。
關於注解的知識點,可以看我上篇隨筆內容。
2.Spring引入context名稱空間
在MyEclipse中導入spring-context-3.2.xsd約束文件,要求Spring來管理。
在applicationContext.xml文件中,引入該schema文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-3.2.xsd 9 "> 10 </beans>
**可以將以上頭信息加入MyEclipse模板中,方便后續自動生成使用。
3.Spring注解實現IOC
(1)開啟包掃描
在spring的配置文件中,開啟包掃描,指定spring自動掃描哪些個包下的類。只有在指定的掃描包下的類上的IOC注解才會生效。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-3.2.xsd 9 "> 10 <!-- 開啟包掃描 --> 11 <context:component-scan base-package="cn.tedu.beans"></context:component-scan> 12 <!-- 13 <bean id="person" class="cn.tedu.beans.Person"></bean> 14 <bean id="cat" class="cn.tedu.beans.Cat"></bean> 15 <bean id="dog" class="cn.tedu.beans.Dog"></bean> 16 --> 17 </beans>
(2)使用注解注冊bean
在配置的包中的類上使用@Component注解,則這個類會自動被注冊成為bean,使用當前類的class為<bean>的class,通常情況下使用類名首字母小寫為<bean>id。
案例:
1 package cn.tedu.beans; 2 import org.springframework.stereotype.Component; 3 4 @Component 5 public class Person{ 6 }
(3)bean的id
通常情況下注解注冊bean使用類名首字母小寫為bean的id,但是如果類名第二個字母為大寫則首字母保留原樣。
1 cn.tedu.beans.Person --> <bean id="person" class="cn.tedu.beans.Person"/> 2 cn.tedu.beans.PErson --> <bean id="PErson" class="cn.tedu.beans.Person"/> 3 cn.tedu.beans.NBA --> <bean id="NBA" class="cn.tedu.beans.NBA"/>
也可以通過在@Component中配置value屬性,明確的指定bean的id
案例:
**可以使bean實現BeanNameAware接口,並實現其中的setBeanName方法。
spring容器會在初始化bean時,調用此方法告知當前bean的id。通過這個方式可以獲取bean的id信息。
1 package cn.tedu.beans; 2 import org.springframework.beans.factory.BeanNameAware; 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Qualifier; 5 import org.springframework.stereotype.Component; 6 7 @Component("per") 8 public class Person implements BeanNameAware{ 9 @Override 10 public void setBeanName(String name) { 11 System.out.println("==="+this.getClass().getName()+"==="+name); 12 } 13 }
4.Spring注解方式實現DI
(1)在配置文件中開啟注解實現DI
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:util="http://www.springframework.org/schema/util" 5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-3.2.xsd 10 http://www.springframework.org/schema/util 11 http://www.springframework.org/schema/util/spring-util-3.2.xsd 12 "> 13 <!-- 開啟IOC包掃描 --> 14 <context:component-scan base-package="cn.tedu.domain"/> 15 <!-- 開啟注解配置DI --> 16 <context:annotation-config></context:annotation-config> 17 </beans>
(2)注解方式注入spring內置支持的類型數據 - 非集合類型
spring中可以通過@Value來實現spring內置支持的類型的屬性的注入。
1 package cn.tedu.domain; 2 3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.stereotype.Component; 5 6 @Component 7 public class Student { 8 @Value("zs") 9 private String name; 10 11 @Value("19") 12 private int age; 13 14 @Override 15 public String toString() { 16 return "Student [name=" + name + ", age=" + age + "]"; 17 } 18 }
這種方式可以實現spring內置支持類型的注入,但是這種方式將注入的值寫死在了代碼中,后續如果希望改變注入的值,必須來修改源代碼,此時可以將這些值配置到一個properties配置文件中,再從spring中進行引入。
(3)注解方式注入spring內置支持的數據類型 - 集合類型
將spring-util-3.2xsd交給MyEclipse管理
在當前spring容器的配置文件中導入util名稱空間
在通過適當的util標簽注冊數據
案例:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:util="http://www.springframework.org/schema/util" 5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-3.2.xsd 10 http://www.springframework.org/schema/util 11 http://www.springframework.org/schema/util/spring-util-3.2.xsd 12 "> 13 <!-- 開啟IOC包掃描 --> 14 <context:component-scan base-package="cn.tedu.domain"/> 15 <!-- 開啟注解配置DI --> 16 <context:annotation-config></context:annotation-config> 17 <!-- 引入Properties文件 --> 18 <context:property-placeholder location="classpath:/stu.properties"/> 19 20 <!-- 配置集合數據 --> 21 <util:list id="l1"> 22 <value>aaa</value> 23 <value>bbb</value> 24 <value>ccc</value> 25 </util:list> 26 <util:set id="s1"> 27 <value>111</value> 28 <value>222</value> 29 <value>333</value> 30 </util:set> 31 <util:map id="m1"> 32 <entry key="k1" value="v1"></entry> 33 <entry key="k2" value="v2"></entry> 34 <entry key="k3" value="v3"></entry> 35 </util:map> 36 <util:properties id="p1"> 37 <prop key="p1">v1</prop> 38 <prop key="p2">v2</prop> 39 <prop key="p3">v3</prop> 40 </util:properties> 41 </beans>
再在類的屬性中通過@Value注入賦值
1 package cn.tedu.domain; 2 3 import java.util.List; 4 import java.util.Map; 5 import java.util.Properties; 6 import java.util.Set; 7 8 import org.springframework.beans.factory.annotation.Value; 9 import org.springframework.stereotype.Component; 10 11 @Component 12 public class Student { 13 @Value("${name}") 14 private String name; 15 16 @Value("${age}") 17 private int age; 18 19 @Value("#{@l1}") 20 private List<String> list; 21 22 @Value("#{@s1}") 23 private Set<String> set; 24 25 @Value("#{@m1}") 26 private Map<String,String> map; 27 28 @Value("#{@p1}") 29 private Properties prop; 30 31 @Override 32 public String toString() { 33 return "Student [name=" + name + ", age=" + age + ", list=" + list 34 + ", set=" + set + ", map=" + map + ", prop=" + prop + "]"; 35 } 36 37 }
(4)使用注解注入自定義bean類型數據
在bean中的屬性上通過@Autowired實現自定義bean類型的屬性注入代碼:
1 package cn.tedu.domain; 2 3 import java.util.List; 4 import java.util.Map; 5 import java.util.Properties; 6 import java.util.Set; 7 8 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Value; 10 import org.springframework.stereotype.Component; 11 12 @Component 13 public class Student { 14 @Autowired 15 private Dog dog; 16 17 @Autowired 18 private Cat cat; 19 20 @Override 21 public String toString() { 22 return "Student [dog="+ dog + ", cat=" + cat + "]"; 23 } 24 25 }
當spring容器解析到@Component注解時,會創建當前類的bean在spring容器中進行管理,在創建bean的過程中發現了@Autowired注解,會根據當前bean屬性名稱,尋找在spring中是否存在id等於該名稱的bean,如果存在則自動注入,如果不存在,在檢查是否存在和當前bean屬性類型相同的bean,如果存在就注入,否在拋出異常。
也可以使用@Qualifier(value="dog1")注解,明確的指定要注入哪個id的bean
**也可以使用@Resource(name="id")指定注入給定id的bean,但是這種方式不建議使用。
5.其他注解
@Scope(value="prototype")
配置修飾的類的bean是單例或者多例,如果不配置默認為單例
案例:
1 package cn.tedu.domain; 2 3 import org.springframework.context.annotation.Scope; 4 import org.springframework.stereotype.Component; 5 6 @Component 7 @Scope("prototype") 8 public class Teacher { 9 }
@Lazy
配置修飾的類的bean采用懶加載機制
案例:
1 package cn.tedu.domain; 2 3 import org.springframework.context.annotation.Lazy; 4 import org.springframework.stereotype.Component; 5 6 @Component 7 @Lazy 8 public class Teacher { 9 public Teacher() { 10 System.out.println("teacher construct.."); 11 }
@PostConstruct
在bean對應的類中,修飾某個方法,將該方法聲明為初始化方法,對象創建之后立即執行。
@PreDestroy
在bean對應的類中,修飾某個方法,將該方法聲明為銷毀的方法,對象銷毀之前調用的方法。
案例:
1 package cn.tedu.beans; 2 import javax.annotation.PostConstruct; 3 import javax.annotation.PreDestroy; 4 import org.springframework.stereotype.Component; 5 6 @Component 7 public class Dog { 8 public Dog() { 9 System.out.println("Dog...被創建出來了..."); 10 } 11 12 @PostConstruct 13 public void init(){ 14 System.out.println("Dog的初始化方法。。。"); 15 } 16 17 @PreDestroy 18 public void destory(){ 19 System.out.println("Dog的銷毀方法。。。"); 20 } 21 }
@Controller @Service @Repository @Component
這四個注解的功能是完全一樣的,都是用來修飾類,將類聲明為Spring管理的bean的。
其中@Component一般認為是通用的注釋
而@Controller用在軟件分層的控制層,一般在web層
而@Service用在軟件分層中的訪問層,一般用在service層
而@Repository用在軟件分層的數據訪問層,一般在dao層