zoukankan      html  css  js  c++  java
  • Spring IOC 注入方式

    依赖注入通常有如下两种方式:

    设值注入:IOC容器使用属性的Setter方法来注入被依赖的实例。

    设值注入是指IOC容器使用属性的Setter方法来注入被依赖的实例。这种注入方式简单、直观,因而在Spring的依赖注入里大量使用。

    构造注入:IOC容器使用构造器来注入被依赖的实例。

    构造注入在构造实例时,已经为其完成了依赖关系的初始化。这种利用构造器来设置依赖关系的方式,被称之为构造注入。

    Spring推荐面向接口编程,可以更好的让规范和实现分离,从而提供更好的解耦。

    对于一个JAVAEE应用,不管是DAO组件,还是业务逻辑组件,都应该先定义一个接口,该接口定义组件应该实现的功能,但是功能的实现则由其实现类提供。

    EX:

    定义一个java类:

    package com.my.model;
    
    public class User  implements Serializable {
    /**
         * 
         */
        private static final long serialVersionUID = -8149950197297816144L;
    private int id;
    private String u_name;
    private String pwd;
    
    public User() {
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getU_name() {
        return u_name;
    }
    public void setU_name(String u_name) {
        this.u_name = u_name;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    
    
    }

    定义2个接口:

    package com.my.dao;
    import com.my.model.User;
    /**
     * 用户管理Dao接口
     * 
     * */
    public interface IUserDao {
    public void saveUser(User u);
    }
    package com.my.service;
    
    import com.my.model.User;
    /**
     * 用户管理Service接口
     * 
     * */
    public interface IUserService {
    public void saveUser(User u);
    }
    package com.my.service;
    
    import com.lovo.model.User;
    /**
     * 用户管理Dao实现类
     * 
     * */
    public class  UserDaoImpl implements  IUserDao{
    public void saveUser(User u){
    //获取session,持久化对象
    }
    }
    package com.my.service;
    
    import com.my.model.User;
    /**
     * 用户管理Service实现类
     * 
     * */
    public class  UserServiceImpl implements  IUserDao{
    private IUserDao userDaoImpl;
    public void saveUser(User u){
    UserDaoImpl.saveUser(u);
    }
    /**
    *set注入
    */
    public void setUserDaoImpl(IUserDao userDaoImpl){ this.userDaoImpl=userDaoImpl; } }

    最后,我们在applicationContext.xml的<beans></beans>中分别配置2个JAVABEAN实例,并配置其关系管理。如:

    <!--由Spring容器创建实例对象,并管理对象之间的关系   -->
    <bean id="userDaoImpl" class="com.my.dao.impl.UserDaoImpl"></bean>
    
    <!--Spring不仅能注入普通属性,也可以注入关系,不再由调用者管理关系   -->
    <bean id="userServiceImpl" class="com.my.dao.impl.UserServiceImpl">
    <property name="userDaoImpl" ref="userDaoImpl"></property >
    </bean>

    在配置文件中,Spring配置Bean实例通常会指定2个属性:

    Id:指定该Bean的唯一标识,程序通过ID属性值来访问该BEAN实例。

    Class:指定该BEAN的实现类,此处不可再用接口,必须使用实现类,Spring容器会使用XML解析器读取该属性值,并利用反射来创建该实现类的实例。

    得到SpringIOC容器的3个基本要点:

    1、 应用程序的各组件面向接口编程。面向接口编程可以讲各组件之间的耦合提示到接口层次,从而有利于项目后期的发展。

    2、 应用程序的各组件不再由程序主动产生,而是由Spring容器来负责产生、并初始化。

    3、 Spring采用配置文件、或Annotation来管理Bean的实现类、依赖关系,Spring容器则根据配置文件、利用反射来创建实例,并为之注入依赖关系。

     

     

    构造注入:

    将上面方法中的Service实现类改为下面的方式:

    package com.my.service;
    
    import com.my.model.User;
    /**
     * 用户管理Service实现类
     * 
     * */
    public class  UserServiceImpl implements  IUserDao{
    private IUserDao userDaoImpl;

    //默认的构造器,如果要设置有参构造,需要先显示执行无参构造

    public UserServiceImpl(){}
    
    

    /**

    
    

     * 构造注入所需的带参数的构造器

     * @param UserDao

     */

    public UserServiceImpl(IUserDao userDao){
    this.userDaoImpl=userDao;
    }
    public void saveUser(User u){ userDaoImpl.saveUser(u); } }

    applicationContext.xml中添加配置为:

    <!--由Spring容器创建实例对象,并管理对象之间的关系   -->
    <bean id="userDaoImpl" class="com.my.dao.impl.UserDaoImpl"></bean>
    
    <!--使用构造注入,为 UserServiceImpl实例注入userDaoImpl实例  -->
    <bean id="userServiceImpl" class="com.my.dao.impl.UserServiceImpl">
    <constructor-arg  ref="userDaoImpl"></constructor-arg>
    </bean>

    两种注入方式的对比:

    Spring同时支持两种依赖注入方式:设置注入和构造注入。两种注入方式,并没有绝对的好坏之分,只是适应的场景有所不同。

    相比之下,设置注入具有如下优点:

    1、 与传统的JavaBean的写法更相识,程序开发人员更容易理解、接受、通过setter方式设定依赖关系显得更加直观、自然。

    2、 对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而导致性能下降。而使用设置注入,则可以避免。

    3、 尤其是在某些属性可选的情况下,多参数的构造器更加笨重。

    当然,构造注入也不是绝对不如设值注入,某些特定的场合,构造更适合。构造也有如下优点:

    1、 构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入,常常需要依赖于Datasource的注入。采用构造注入,可以在代码中清晰地决定注入顺序。

    2、 对于依赖关系无须变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器中设定,因此,无须担心后续的代码对依赖关系产生破坏。

    3、 依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系。对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。

    建议采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无须变化的注入,尽量采用构造注入;而其他的依赖关系的注入,则考虑采用设值注入。

  • 相关阅读:
    动态调用web服务
    组件设计实战--组件之间的关系 (Event、依赖倒置、Bridge)
    .NET平台下可复用的Tcp通信层实现
    推荐所有的.NET开发人员阅读《J2EE Development without EJB》
    关于跨程序集的反射(续)
    IoC与DI (转载)
    某公司的一道机考题的解答
    使用 EmptyClass 避免条件判断
    EsbAOP应用--权限管理
    企业(分布式)计算十大谬误
  • 原文地址:https://www.cnblogs.com/Spirit612/p/5090017.html
Copyright © 2011-2022 走看看