zoukankan      html  css  js  c++  java
  • 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注解才会生效。

     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层

  • 相关阅读:
    JSR303实现数据校验案例
    maven安装和相关配置
    mybatis分页插件使用案例
    分页查询案例
    ssm整合相关配置
    配置文件没有按照maven约定存放解决方法
    git常用命令和基本使用
    mybatis配置二级缓存
    Angular第三方UI组件库------ionic
    Angular路由知识点
  • 原文地址:https://www.cnblogs.com/xiaoluohao/p/11253521.html
Copyright © 2011-2022 走看看