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层