Spring注入方式介绍

来源:互联网 发布:c语言中开根号 编辑:程序博客网 时间:2024/05/16 11:31

http://my.oschina.net/wlb/blog/282958#OSC_h2_10


目录[-]

  • 一、Spring注入基础
  • (1)开篇准备
  • (2)Spring注入的基本步骤
  • 二、Spring注入方式介绍
  • (1)属性注入
  • (2)构造方法注入
  • (3)自动注入
  • (4)Annotation注入
  • 三、知识扩展
  • (1)Spring注入方式最佳实践
  • (2)JavaBean关于属性命名的特殊规范
  • 一、Spring注入基础

            Spring为我们提供了丰富的注入方式,本文将逐一介绍。

    (1)开篇准备

            开篇我们需要先准备一个接近真实项目的项目环境。项目的层次结构如下:

      1. com.uni2uni.spring.model:实体层。

      2. com.uni2uni.spring.dao:数据访问接口层。        

      3. com.uni2uni.spring.dao.impl:数据访问接口实现层。

      4. com.uni2uni.spring.service:业务逻辑接口层。

      5. com.uni2uni.spring.service.impl:业务逻辑接口实现层。

      6. com.uni2uni.spring.action:struts2的Action层。

      7. com.uni2uni.spring.test:测试层。

      最终项目的目录结构如下图所示:

      按照层次接口类的代码分别如下:

      User.java代码如下:

      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      package com.uni2uni.spring.model;
      public class User {
       publicint getId() {
        returnid;
       }
       publicvoid setId(intid) {
        this.id = id;
       }
       publicString getUsername() {
        returnusername;
       }
       publicvoid setUsername(String username) {
        this.username = username;
       }
       privateint id;
       privateString username;
       @Override
       publicString toString() {
        return"User [id=" + id + ", username=" + username +"]";
       }
        
       publicUser() {
       }
       publicUser(int id, String username) {
        super();
        this.id = id;
        this.username = username;
       }
        
      }

      IUserDao.java代码如下:

      ?
      1
      2
      3
      4
      5
      6
      7
      package com.uni2uni.spring.dao;
      import com.uni2uni.spring.model.User;
      public interface IUserDao {
       publicvoid add(User user);
       publicvoid delete(intid);
       publicUser get(int id);
      }

      UserDao.java代码如下:

      ?
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      package com.uni2uni.spring.dao.impl;
      import com.uni2uni.spring.dao.IUserDao;
      import com.uni2uni.spring.model.User;
      public class UserDao implementsIUserDao{
       @Override
       publicvoid add(User user) {
        System.out.println("添加了"+user); 
       }
       @Override
       publicvoid delete(intid) {
         
        System.out.println("删除了"+id);
       }
       @Override
       publicUser get(int id) {
        System.out.println("获取了"+id);
        returnnull;
       }
        
      }

      IUserService.java代码如下:

      ?
      1
      2
      3
      4
      5
      6
      7
      package com.uni2uni.spring.service;
      import com.uni2uni.spring.model.User;
      public interface IUserService {
       publicvoid add(User user);
       publicvoid delete(intid);
       publicUser Get(int id);
      }

            UserService.java代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package com.uni2uni.spring.service.impl;
    import com.uni2uni.spring.dao.IUserDao;
    import com.uni2uni.spring.model.User;
    import com.uni2uni.spring.service.IUserService;
    public class UserService  implementsIUserService{
     privateIUserDao userDao;
     publicIUserDao getUserDao() {
      returnuserDao;
     }
     publicvoid setUserDao(IUserDao userDao) {
      this.userDao = userDao;
     }
     @Override
     publicvoid add(User user) {
      userDao.add(user);
     }
     @Override
     publicvoid delete(intid) {
      userDao.delete(id); 
     }
     @Override
     publicUser Get(int id) {
      userDao.get(id);
      returnnull;
     }
    }

            spring-conf.xml代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <?xml version="1.0"encoding="UTF-8"?>
    <beans xmlns="
    http://www.springframework.org/schema/beans
    "
     xmlns:xsi="
    http://www.w3.org/2001/XMLSchema-instance
    "
     xsi:schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    ">
     <bean id="userDao"class="com.uni2uni.spring.dao.impl.UserDao"/>
     <bean id="userService"class="com.uni2uni.spring.service.impl.UserService">
      <property name="userDao"ref="userDao"></property>
     </bean>
     <bean id="userAction"class="com.uni2uni.spring.action.UserAction">
      <property name="userService"ref="userService"></property>
     </bean>
    </beans

            TestSpring.java中的内容如下所示:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.uni2uni.spring.test;
    import junit.framework.TestCase;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import com.uni2uni.spring.action.UserAction;
    import com.uni2uni.spring.model.User;
    public class TestSpring extendsTestCase{
     privateBeanFactory factory=newClassPathXmlApplicationContext("spring-conf.xml");
      
     publicvoid test1(){
      UserAction ua= factory.getBean("userAction",UserAction.class);
      User u =new User(1,"张三");
      ua.setUser(u);
      ua.add();
     }
    }

    (2)Spring注入的基本步骤

            Spring注入的基本步骤如下:

      1. 将所有的类在spring-conf.xml中创建bean

        语法如下:

        <bean id="beanId" class="包名.类名">

      2. 对所有依赖的类进行注入

        1. 如果是属性注入,需要为每一个依赖类创建相应的getter和setter方法

        2. 如果是构造方法注入,需要为依赖类创建相应的构造方法            

      3.  在测试方法中测试是否正确注入

    二、Spring注入方式介绍

    (1)属性注入

            属性注入的语法如下:

            <bean id="被注入的类的beanId" class="包名.类名" />

            <bean id="beanId" class="包名.类名">
                  <property name="被注入的bean的名字" ref="被注入的类的beanId"></property>
             </bean>

            在本例中,属性注入的具体配置如下:

    ?
    1
    2
    3
    4
    <bean id="userDao"class="com.uni2uni.spring.dao.impl.UserDao"/>
     <bean id="userService"class="com.uni2uni.spring.service.impl.UserService">
      <property name="userDao"ref="userDao"></property>
     </bean>

            因为UserService依赖与UserDao,因此需要在userService中创建相应的getter和setter方法。UserService中的属性定义如下所示:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.uni2uni.spring.service.impl;
    import com.uni2uni.spring.dao.IUserDao;
    import com.uni2uni.spring.model.User;
    import com.uni2uni.spring.service.IUserService;
      
    public class UserService  implementsIUserService{
      
     privateIUserDao userDao;
     publicIUserDao getUserDao() {
      returnuserDao;
     }
     publicvoid setUserDao(IUserDao userDao) {
      this.userDao = userDao;
     }
      ......省略部分代码
    }

    (2)构造方法注入

            构造方法注入的语法如下:

            <bean id="被注入的类的beanId" class="包名.类名" />

            <bean id="beanId" class="包名.类名">
                  <constructor-arg ref="被注入的类的beanId" />         

            </bean>

            本例中,构造方法注入的具体配置如下:

    ?
    1
    2
    3
    4
    <bean id="userService"class="com.uni2uni.spring.service.impl.UserService"/>
     <bean id="userAction"class="com.uni2uni.spring.action.UserAction">
      <constructor-arg ref="userService"/>
     </bean>

            由于本例中使用构造方法注入,因此需要在UserAction中编写UserService的构造方法,UserAction中的构造方法定义如下所示:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package com.uni2uni.spring.action;
    import com.uni2uni.spring.model.User;
    import com.uni2uni.spring.service.IUserService;
      
    public class UserAction {
     privateIUserService userService;
     
     publicUserAction(IUserService userService) {
      super();
      this.userService = userService;
     }
        ......省略部分代码
    }

    (3)自动注入

            自动注入语法如下所示:

            <bean id="beanId" class="包名.类名" autowire="参数值" />

            autowire的参数值可选有:“default”、“byName”、“byType”、“constructor”、“no”。

            default:根据bean的自省机制决定采用byType还是constructor进行自动装配,如果Bean提供了默认的构造函数,则采用byType,否则采用constructor。

            byName:通过属性名自动注入。

            byType:通过属性类型自动注入。

            constructor:与byType相同,但作用于构造器。

            no:不自动注入。

    (4)Annotation注入

            Spring在3.0以后,提供了基于Annotation(注解)的注入。

            这种方式是在类名上使用注解的方式进行注入。

            Annotation注入的步骤如下:

            a.配置spring.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="
    http://www.springframework.org/schema/beans"
         xmlns:xsi="
    http://www.w3.org/2001/XMLSchema-instance"
         xmlns:aop="
    http://www.springframework.org/schema/aop"
         xmlns:context="
    http://www.springframework.org/schema/context"
         xsi:schemaLocation="
    http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
             http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-3.0.xsd
             http://www.springframework.org/schema/aop
             http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
       <!--第一步.、打开Spring的Annotation支持 -->
       <context:annotation-config/>
       <!-- 第二步、设定Spring 去哪些包中找Annotation -->
       <context:component-scan base-package="com.uni2uni.spring"/>
       <!-- 第三步、打开基于Annotation的AOP -->
       <aop:aspectj-autoproxy/>
    </beans>

            b.在类上面添加注解

    具体方法是:在类上面加@Component("beanId"),在setter方法上加@Resource即可。如果需要指定scope属性,则添加@Scope("singleton|prototype|...")即可。如下所示:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    package com.uni2uni.spring.action;
    import javax.annotation.Resource;
    import org.springframework.stereotype.Component;
    import com.uni2uni.spring.model.User;
    import com.uni2uni.spring.service.IUserService;
    @Component("userAction")
    @Scope("prototype")
    public class UserAction {
     privateUser user;
     privateIUserService userService;
     privateint id;
     publicUserAction(IUserService userService) {
      super();
      this.userService = userService;
     }
     publicUser getUser() {
      returnuser;
     }
      
     @Resource
     publicvoid setUser(User user) {
      this.user = user;
     }
     publicIUserService getUserService() {
      returnuserService;
     }
     @Resource
     publicvoid setUserService(IUserService userService) {
      this.userService = userService;
     }
     publicint getId() {
      returnid;
     }
     publicvoid setId(intid) {
      this.id = id;
     }
     publicvoid add(){
      userService.add(user);
     }
      
     publicvoid delete(){
      userService.delete(id);
     }
      
     publicvoid Get(){
      userService.Get(id);
     }
    }

            注意:在新的Spring3的标准中,已经不推荐使用@Component的方式来完成bean的创建。新的标准提供了更多的Annotation来替代@Component。例如:

            @Repository:一般用于Dao的注入;

            @Service:一般用于Service层的注入;

            @Controller:一般用于Action层的注入。

    三、知识扩展

    (1)Spring注入方式最佳实践

            Spring注入最常用的是属性注入,构造方法注入、自动注入、Annotation方式的注入一般不用。

            Annotation注入平时多用于一些小项目。

    (2)JavaBean关于属性命名的特殊规范

            一般情况下,Java的属性变量名都以小写字母起头,但也存在特殊情况;

            变量的前两个字母要么全部大写,要么全部小写。


    0 0