• Spring IOC 注入方式详解 附代码


    引言

      Spring框架作为优秀的开源框架之一,深受各大Java开发者的追捧,相信对于大家来说并不陌生,Spring之所以这么流行,少不了他的两大核心技术IOC和IOP。我们这里重点讲述Spring框架的IOC技术运用,如何运用好Spring的IOC技术。

      在我们平 常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一 管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。 依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序 员来做而是交给spring容器来做。

      在Spring容器中为一个bean配置依赖注入有三种方式:

       1) 使用属性的setter方法注入 ;

       2) 使用构造器注入;

       3) 使用Filed注入(用于注解方式)

    准备工作

      在开始我们的学习之旅前,我们需要准备IOC必备的开发包。

      资源下载链接:http://download.csdn.net/detail/yfyzy/8912543

    一.使用属性的setter方法注入

       首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性,并且拥该属性或数据类型的set方法。

    setter注入-示例:

     1 //我们首先定义一个UserDao的接口
     2 interface UserDao {
     3 
     4     public void say();
     5 }
     6 
     7 
     8 //定义一个类,并且实现我们的UserDao接口
     9 class UserDaoImpl implements UserDao {
    10     
    11     @Override
    12     public void say() {
    13         System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过set方法创建的。");
    14     }
    15 }
    16 
    18 class UserService {
    19 
    20     //注意这里定义的userDao是接口的引用。当然也可以是 UserDaoImpl userDao 。
    21     //我们提倡用前者,面向接口编程,来降低我们代码的耦合度!!!
    22     private UserDao userDao;
    23 
    24     public void setUserDao(UserDao userDAO) {
    25         this.userDao = userDAO;
    26     }
    27 
    28     public void fun() {
    29         
    30         System.out.println("我要执行真正的逻辑操作了");
    31         
    32         //请注意,在整个过程中,我们并没有手动实例化过userDao对象,而是让Spring容器为我们实例化的
    33         userDao.say();
    34     }
    35 }
    36
    38 public class SetTest {
    39 
    40     public static void main(String[] args) {
    41         ApplicationContext context = new ClassPathXmlApplicationContext("set.xml");
    42         
    43         // 2、从容器中获取Bean
    44         UserService userDao = context.getBean("userService", UserService.class);
    45         
    46         // 3、执行业务逻辑
    47         userDao.fun();
    48     }
    49 }

    set.xml配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans        
     6         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     7         http://www.springframework.org/schema/context                
     8         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
     9 
    10     <bean id="userService" class="UserService">
    11           <!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->
    12         <property name="userDao" ref="userDao"></property>
    13     </bean>
    14     <bean id="userDao" class="UserDaoImpl"></bean>
    15     
    16 </beans>

      不知道你对上述配置文件是否了解,我们就先简单的介绍一下,<bean>代表一个java对象,id="userService" class="UserService"  ,则相当于我们平时写Java代码的UserService userService 。<property>则是为配置的对象设置属性。<property name="userDao" ref="userDao"></property> 在这个标签中 name 代表着 class="UserService"  这个类的属性,ref 则是指向已经当经定义好的bean对象。请特别留意代码中的那句注释“<!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->”,否则运行时会报错。特别注意了哦!! 在这里我们的class引入的是类的路径: 包名.类型 ,例如在 在com包下有类 Test,则class = "com.Test" 。特别注意了哦。

     

    工厂注入

      有时候,我们希望产生对象是通过我们写工厂方法产生,并且又希望能通过Spring来产生对象,下面我们就来看看Spring如何通过工厂来注入。

    静态工厂注入

      静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,

    而是依然通过Spring注入的形式获取。

    静态工厂注入-示例:

     1 //我们首先定义一个UserDao的接口
     2 interface UserDao {
     3 
     4     public void say();
     5 }
     6 
     7 //定义一个类,并且实现我们的UserDao接口
     8 class UserDaoImpl implements UserDao {
     9     
    10     @Override
    11     public void say() {
    12         System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过工厂的静态方法产生的");
    13     }
    14 }
    15 
    16 //添加静态工厂
    17 class DaoFactory {  
    18     //静态工厂  
    19     public static final UserDao getStaticFactoryDaoImpl(){  
    20         return new UserDaoImpl();  
    21     }  
    22 }  
    23 
    24 class UserService {
    25 
    26     private UserDao userDao;
    27 
    28     public void setUserDao(UserDao userDao) {
    29         this.userDao = userDao;
    30     }
    31 
    32     public void fun() {
    33         userDao.say();
    34     }
    35 }
    36 
    37 public class FactoryStaticsTest {
    38 
    39     public static void main(String[] args) {
    40 
    41         ApplicationContext context = new ClassPathXmlApplicationContext("factory.statics.xml");
    42         
    43         // 2、从容器中获取Bean
    44         UserService userDao = context.getBean("userService", UserService.class);
    45         
    46         // 3、执行业务逻辑
    47         userDao.fun();
    48     }
    49 
    50 }

     factory.statics.xml配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans        
     6         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     7         http://www.springframework.org/schema/context                
     8         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
     9 
    10     <bean id="userService" class="factory.statics.UserService">
    11           <!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->
    12         <property name="userDao" ref="userDao"></property>
    13     </bean>
    14     <bean id="userDao" class="factory.statics.DaoFactory" 
    15     factory-method="getStaticFactoryDaoImpl"></bean>
    16 </beans>

    实例工厂的方法注入

      实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法。(PS: 先有工厂对象,在通过工厂的对象来产生我们的业务逻辑对象。)

    实例工厂注入-示例:

     1 //我们首先定义一个UserDao的接口
     2 interface UserDao {
     3 
     4     public void say();
     5 }
     6 
     7 //定义一个类,并且实现我们的UserDao接口
     8 class UserDaoImpl implements UserDao {
     9     @Override
    10     public void say() {
    11         System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过工厂的实例方法产生的");
    12     }
    13 }
    14 
    15 //添加工厂类
    16 class DaoFactory {  
    17     
    18     //产生UserDao对象
    19     public  UserDao getFactoryDaoImpl(){  
    20         return new UserDaoImpl();  
    21     }  
    22 }  
    23 
    24 class UserService {
    25 
    26     private UserDao userDao;
    27 
    28     public void setUserDao(UserDao userDao) {
    29         this.userDao = userDao;
    30     }
    31 
    32     public void fun() {
    33         userDao.say();
    34     }
    35 }
    36 
    37 public class FactoryObject {
    38 
    39     public static void main(String[] args) {
    40         ApplicationContext context = new ClassPathXmlApplicationContext("factory.object.xml");
    41         
    42         // 2、从容器中获取Bean
    43         UserService userDao = context.getBean("userService", UserService.class);
    44         
    45         // 3、执行业务逻辑
    46         userDao.fun();
    47     }
    48 }

     factory.object.xml 配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans        
     6         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     7         http://www.springframework.org/schema/context                
     8         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
     9 
    10     <bean id="userService" class="factory.object.UserService">
    11           <!--依赖注入,配置当前类中相应的属性,该属性必须有对应的set方法-->
    12         <property name="userDao" ref="userDao"></property>
    13     </bean>
    14     <bean id="daoFactory" class="factory.object.DaoFactory"></bean>
    15     <bean id="userDao" factory-bean="daoFactory" 
    16     factory-method="getFactoryDaoImpl"> </bean>
    17 </beans>

    二.使用构造器注入

      使用构造器注入方式,不用为该类的属性属性设置setter方法,但是需要生成该类的相应的构造方法构造方法。

    构造器注入-示例:

     1 //我们首先定义一个UserDao的接口
     2 interface UserDao {
     3 
     4     public void say();
     5 }
     6 
     7 //定义一个类,并且实现我们的UserDao接口
     8 class UserDaoImpl implements UserDao {
     9     @Override
    10     public void say() {
    11         System.out.println("我是UserDaoImpl类,我是实现了UserDao接口,我是通过构造方法创建的。");
    12     }
    13 }
    14 
    15 class UserService {
    16 
    17     private UserDao userDao;
    18     
    19     public UserService(UserDao userDao){
    20         this.userDao = userDao;
    21     }
    22 
    23     public void fun() {
    24         userDao.say();
    25     }
    26 }
    27 
    28 
    29 public class ConstructorTest {
    30 
    31     public static void main(String[] args) {
    32         
    33         ApplicationContext context = new ClassPathXmlApplicationContext("construct.xml");
    34         
    35         // 2、从容器中获取Bean
    36         UserService userDao = context.getBean("userService", UserService.class);
    37         
    38         // 3、执行业务逻辑
    39         userDao.fun();
    40     }
    41 
    42 }

    construct.xml 配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xsi:schemaLocation="
     6         http://www.springframework.org/schema/beans        
     7         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     8         http://www.springframework.org/schema/context                
     9         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    10 
    11     <bean id="userService" class="constructor.UserService">
    12         <!--创建构造器注入,如果主类有带参的构造方法则需添加此配置 -->
    13         <constructor-arg index="0" ref="userDao"></constructor-arg>
    14     </bean>
    15     <bean name="userDao" class="constructor.UserDaoImpl"></bean>
    16 </beans>

     

    三.使用字段(Filed)注入(用注解方式)

      在学习注解注入方式之前,我们首先了解从spring2.5增加的新特性,这些新特性包括:

      注解驱动的依赖性注入(annotation- driven dependency injection),使用注解而非XML元数据来自动侦测classpath上的Spring组件,注解对生命周期方法的支持,一个新的web控制器模 型将请求映射到加注解的方法上,在测试框架中支持Junit4,Spring XML命名空间的新增内容,等等。

    在Spring中,注入依赖对象可以采用手工装配或自动装配,在实际应用开发中建议使用手工装配,因为自动装配会产生许多未知情况,开发人员无法预见最终的装配结果。

    手工装配依赖对象又分为两种方式:

    1)一种是在XML文件中,通过在bean节点下配置;如上面讲到的使用属性的setter方法注入依赖对象和使用构造器方法注入依赖对象都是这种方式。

    2)另一种就是在java代码中使用注解的方式进行装配,在代码中加入@Resource或者@Autowired

    怎样使用注解的方式来为某个bena注入依赖对象呢?

    首先,我们需要在Spring容器的配置文件applicationContext.Xml文件中配置以下信息,该信心是一个Spring配置文件的模板:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 
     3 <beans
     4 
     5 xmlns="http://www.springframework.org/schema/beans"
     6 
     7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     8 
     9 xmlns:context="http://www.springframework.org/schema/context"
    10 
    11 xmlns:p="http://www.springframework.org/schema/p"
    12 
    13 xsi:schemaLocation="http://www.springframework.org/schema/beans 
    14 
    15 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    16 
    17 http://www.springframework.org/schema/context
    18 
    19 http://www.springframework.org/schema/context/spring-context-2.5.xsd
    20 
    21 ">
    22 
    23 </beans>

    为了获得新的的特性  首先要引入新的context的Schema命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会 做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。

    注意:只有配置了红色部分的代码 才可以引入注解的命名空间,否则报错。  以上的配置隐式的注册了多个对注释进行解析的处理 器:AutowiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 等。

    其次,在配置文件中打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象;其在配置文件中的代码如下:

    <beans>

    ……

    <context:annotation-config></context:annotation-config>

    ……

    </beans>

    第三,在配置文件中配置bean对象,如下:

       <bean id="userDao" class="annotation.manul.UserDaoImpl"></bean>
       <bean id="userService" class="annotation.manul.UserService"></bean>

    注解注入-示例:

     1 interface UserDao {
     2 
     3     void say();
     4 }
     5 
     6 
     7 class UserDaoImpl implements UserDao {
     8     @Override
     9     public void say() {
    10         System.out.println("I am created by manual annotation! + UserDaoImpl");
    11     }
    12 }21 
    22 class UserService {
    23 
    24     @Resource(name="userDao")
    25     private UserDao userDao = null;
    26 
    27     public UserDao getUserDao() {
    28         return userDao;
    29     }
    30     
    31     //在该属性的set方法上添加对应的方法,也能达到相同的效果。
    32     /*@Resource(name="userDao")
    33     public void setUserDa(UserDao userDao) {
    34         this.userDao = userDao;
    35     }*/
    36 
    37     public void fun() {
    38         userDao.say();
    39     }
    40 }
    41 
    42 public class AnnotationManulTest {
    43 
    44     public static void main(String[] args) {
    45 
    46         ApplicationContext context = new ClassPathXmlApplicationContext(
    47                 "applicationContext.xml");
    48         
    49         // 2、从容器中获取Bean
    50         
    51         UserService userDao = context.getBean("userService", UserService.class);
    52         
    53         // 3、执行业务逻辑
    54         userDao.fun();
    55     
    56     }
    57 
    58 }

    applicationContext.xml配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans        
     6         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     7         http://www.springframework.org/schema/context                
     8         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
     9     <!-- 打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象 -->
    10     <context:annotation-config></context:annotation-config>
    11  
    14 <bean id="userDao" class="annotation.manul.UserDaoImpl"></bean> 15
    <bean id="userService" class="annotation.manul.UserService"></bean> 16 17 </beans>

      其中,在Java代码中可以使用@Autowired或@Resource注解方式进行Spring的依赖注入。两者的区别是:

      1)@Autowired默认按类型装配。

      2)@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。

      比如:我们用@Autowired为上面的代码UserDAO接口的实例对象进行注解,它会到Spring容器中去寻找与UserDAO对象相匹配的类型,如果找到该类型则将该类型注入到userdao字段中;

      如果用@Resource进行依赖注入,它先会根据指定的name属性去Spring容器中寻找与该名称匹配的类型,例如:@Resource(name="userDao"),如果没有找到该名称,则会按照类型去寻找,找到之后,会对字段userDao进行注入。

    通常我们使用@Resource。

      使用注解注入依赖对象不用再在代码中写依赖对象的setter方法或者该类的构造方法,并且不用再配置文件中配置大量的依赖对象,使代码更加简洁,清晰,易于维护。我们可以直接对属性进行注入,也可以对setter方法,进行注入。以下两种方式都是对的:

      1)@Resource(name="userDao")

          private UserDao userDao ;

          2)  @Resource(name="userDao")

                public void setUserDa(UserDao userDao)

        { this.userDao = userDao; }

      PS:在Spring IOC编程的实际开发中推荐使用注解的方式进行依赖注入

    依赖注入—自动装配

      Spring中提供了自动装配依赖对象的机制,但是在实际应用中并不推荐使用自动装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。自动装配是在配置文件中实现的,如下:

      <bean id="***" class="***" autowire="byType">

      只需要配置一个autowire属性即可完成自动装配,不用再配置文件中写<property>,但是在类中还是要生成依赖对象的setter方法

      Autowire的属性值有如下几个:

      byType 按类型装配  可以根据属性类型,在容器中寻找该类型匹配的bean,如有多个,则会抛出异常,如果没有找到,则属性值为null;       

          byName 按名称装配  可以根据属性的名称在容器中查询与该属性名称相同的bean,如果没有找到,则属性值为null;

       constructor 与byType方式相似,不同之处在与它应用于构造器参数,如果在容器中没有找到与构造器参数类型一致的bean,那么将抛出异常;

         autodetect 通过bean类的自省机制(introspection)来决定是使用constructor还是byType的方式进行自动装配。如果发现默认的构造器,那么将使用byType的方式。

    依赖注入-自动装备-示例:

     1 //我们首先定义一个UserDao的接口
     2 interface UserDao {
     3 
     4     void say();
     5 }
     6 
     7 //定义一个类,并且实现我们的UserDao接口
     8 class UserDaoImpl implements UserDao {
     9     
    10     @Override
    11     public void say() {
    12         System.out.println("I am created by manual annotation! + UserDaoImpl");
    13     }
    14 }
    15 
    16 class UserService {
    17 
    18     private UserDao userDao = null;
    19 
    20     //这个步骤不能少,一定要设置对应的setter方法
    21     public void setUserDao(UserDao userDao) {
    22         this.userDao = userDao;
    23     }
    24     
    25     public void fun() {
    26         userDao.say();
    27     }
    28 }
    29 
    30 public class AnnotationManulTest {
    31 
    32     public static void main(String[] args) {
    33 
    34         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    35         
    36         // 2、从容器中获取Bean
    37         UserService userDao = context.getBean("userService", UserService.class);
    38         
    39         // 3、执行业务逻辑
    40         userDao.fun();
    41     
    42     }
    43 
    44 }

     applicationContext.xml 配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans        
     6         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     7         http://www.springframework.org/schema/context                
     8         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
     9     <!-- 打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象 -->
    10 
    11     <context:annotation-config></context:annotation-config>
    12 
    13     <bean id="userDao" class="annotation.manul.UserDaoImpl"></bean>
    14     <bean id="userService" class="annotation.manul.UserService" autowire="byName"></bean>
    15 
    16 </beans>

    自动扫描 注入(实现零配置)

      spring2.5为我们引入了组件自动扫描机制,它可以在 classPath路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳 入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。

      也就是要spring自动扫描机制只会查找指定类路径下包含@Component、@Service、@Controller、@Repository这四种注解的类。

      要使用自动扫描机制,我们需要打开以下配置信息:

      1、引入context命名空间 需要在xml配置文件中配置以下信息: 同上先引入context 命名空间,同时

      2、在配置文件中添加context:component-scan标签

      <context:component-scan base-package="*"/> 

      其中base-package为需要扫描的包(含子包)。

       注意:

      1、在使用组件扫描元素 时,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor 会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。也就是说如果使用了context:component-scan标签,就可以不需要再引入 context:annotation-config标签

    <context:component-scan />还允许定义过滤器将基包下的某些类纳入或排除。Spring支持以下4种类型的过滤方式:
    过滤器类型 表达式范例 说明:
      1)注解 org.example.SomeAnnotation 将所有使用SomeAnnotation注解的类过滤出来 
      2)类名指定 org.example.SomeClass 过滤指定的类 
      3)正则表达式 com.kedacom.spring.annotation.web..* 通过正则表达式过滤一些类
      4)AspectJ表达式 org.example..*Service+ 通过AspectJ表达式过滤一些类 

    以正则表达式为例,我列举一个应用实例:

    <context:component-scan base-package="com.casheen.spring.annotation">  
      <context:exclude-filter type="regex" expression="com.casheen.spring.annotation.web..*" />
    </context:component-scan>

    <context:component-scan base-package="com.casheen.spring.annotation">
      <context:exclude-filter type="regex" expression="com.casheen.spring.annotation.web..*" />
    </context:component-scan>


      
    注意: <context:component-scan />配置项不但启用了对类包进行扫描以实施注释驱动Bean定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了 AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor), 因此当使用<context:component-scan />后,就可以将<context:annotation-config />移除了。

      需要被扫描的类添加相应的注解,注解的类型有以下几种:

      @Service用于标注业务层组件、

      @Controller用于标注控制层组件(如struts中的action)、

      @Repository用于标注数据访问组件,即DAO组件。

      而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 这四种注解仅仅是角色不同,但实质都一样。

      细节问题总结:

      1.当我们进行测试时,用ApplicationContext对象的getBean()方法寻找组件。在之前的配置文件中我们会用<bean>标签的id属性去定义,在使用自动扫描注解后怎样获得组建的id呢?

      在这种情况下,Spring会将被标注注解的类名,然后再将该类名的第一个字母变为小写,放到getBean()方法中。如:UserBizImpl类的组件Id就会是userBizImpl,获取时为context.getBean("userBizImpl");

      2.那么,我们在使用注解时可以自定义组件的Id吗?

      当然可以。我们需要在为相应的类添加注解时,在注解之后添加自定义的类名,例如:

      @Service("userBiz")

      public class UserBizImpl implements UserBiz {

      ……

      }

      当我们在获取该组件时,为context.getBean("userBiz);

      3.在配置文件中我们可以对组件(bean)的作用域范围进行设置,它的默认值是单例模式,那么在添加注解的情况下,我们怎样设置组件的作用域范围呢?

      我们可以直接在为类添加注解的同时,运用另一个注解@Scope("prototype")来设置,如下

      @Service("userBiz")@Scope("prototype")

      public class UserBizImpl implements UserBiz {

      ……

      }

      4.在使用注解时,为组件设置初始化和销毁方法:

      在添加注解的相应的类中,如果想初始化或销毁某个方法,我们可以直接在方法上添加注解,如下:

      @PostConstruct

      public void addItem() {

      System.out.println("初始化方法");

      }

      @PreDestroy

      public void testItem() {

      System.out.println("释放资源");

      }

      5.在使用Spring自动扫描组件后,怎样进行依赖注入?

      运用注解@Resource和@Autowired,并为依赖对象设置名称,例如:

      @Resource(name="userDao")

      private UserDAO userDao = null;

      首先它会根据名称去找Spring自动扫描的并加入到Spring容器的组件(bean),如果有相同的名称,则进行依赖注入,如果没有相同的名称。则会根据类型  区寻找组件。

      理解以上的内容后,你就可以很轻松的实现spirng零配置了 O(∩_∩)O。

    自动扫描注入-示例:

     1 //我们首先定义一个UserDao的接口
     2 interface UserDao {
     3 
     4     void say();
     5 }
     6 
     7 //定义一个类,并且实现我们的UserDao接口
     8 @Repository("userDao")     //@Repository用于标注数据访问组件,即DAO组件.注解仅仅是角色不同,但实质都一样。
     9 class UserDaoImpl implements UserDao {
    10     
    11     @Override
    12     public void say() {
    13         System.out.println("I am created by manual annotation! + UserDaoImpl");
    14     }
    15 }
    16 
    17 @Service("userService")
    18 class UserService {
    19 
    20     private UserDao userDao = null;
    21 
    22     //这个步骤不能少,一定要设置对应的setter方法
    23     @Resource
    24     public void setUserDao(UserDao userDao) {
    25         this.userDao = userDao;
    26     }
    27     
    28     public void fun() {
    29         userDao.say();
    30     }
    31 }
    32 
    33 public class AnnotationManulTest {
    34 
    35     public static void main(String[] args) {
    36 
    37         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    38         
    39         // 2、从容器中获取Bean
    40         UserService userDao = context.getBean("userService", UserService.class);
    41         
    42         // 3、执行业务逻辑
    43         userDao.fun();
    44     }
    45 }

     applicationContext.xm配置

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xsi:schemaLocation="
     6         http://www.springframework.org/schema/beans        
     7         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     8         http://www.springframework.org/schema/context                
     9         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    10 
    11    <context:component-scan base-package="annotation.manul"></context:component-scan> 
    12 
    13     <!--运用自动扫描注入,就不需要下面的配置了,这个已经包含进去了-->
    14     <!-- 打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象 -->
    15 
    16 </beans>

    ------------------------------------------------------------------------------------------------

      以上就是关于spring注入的介绍,怎么样,比较简单吧,~O(∩_∩)O~。

  • 相关阅读:
    向TRichEdit插入图片的单元
    等待程序结束后, 自动启动程序的批处理
    执行程序函数
    基于IWICImage的截图代码
    线程中WICImage与Bitmap数据转换
    清理win10过期补丁的命令
    [转] 常见的哈希函数
    豆瓣小组爬虫.....^_^
    如何在ASP.NET Core中实现CORS跨域
    在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证
  • 原文地址:https://www.cnblogs.com/yfyzy/p/4657141.html
Copyright © 2020-2023  润新知