JAVA-Spring注解方式实现IOC和DI

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注解才会生效。

扫描二维码关注公众号,回复: 6877528 查看本文章
 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层

猜你喜欢

转载自www.cnblogs.com/xiaoluohao/p/11253521.html