6.3Java EE——控制反转与依赖注入

一、控制反转的概念

传统面向对象程序设计原则

        控制反转(Inversion of Control,缩写为IoC)是面向对象编程中的一个设计原则,用来降低程序代码之间的耦合度。在传统面向对象编程中,获取对象的方式是用new关键字主动创建一个对象,也就是说应用程序掌握着对象的控制权。传统面向对象程序设计原则如图。

IoC设计原则

         IoC控制反转机制指的是对象由Ioc容器统一管理,当程序需要使用对象时,可以直接从IoC容器中获取。这样对象的控制权就从应用程序转移到了IoC容器。IoC设计原则如图,它是借助于IoC容器实现具有依赖关系对象之间的解耦,各个对象类封装之后,通过IoC容器来关联这些对象类。

二、依赖注入的概念

什么是依赖注入

         依赖注入(Dependency Inject,缩写DI)就是由IoC容器在运行期间动态地将某种依赖资源注入对象之中。例如,将对象B注入(赋值)给对象A的成员变量。依赖注入的基本思想是:明确地定义组件接口,独立开发各个组件,然后根据组件的依赖关系组装运行。

依赖注入和控制反转的比较

        依赖注入(DI)和控制反转(IoC)是从不同角度来描述了同一件事情。依赖注入是从应用程序的角度描述,即应用程序依赖IoC容器创建并注入它所需要的外部资源;而控制反转是从IoC容器的角度描述,即IoC容器控制应用程序,由IoC容器反向地向应用程序注入应用程序所需要的外部资源。这里所说的外部资源可以是外部实例对象,也可以是外部文件对象等。 

三、依赖注入的类型

依赖注入的实现方式

         依赖注入的作用就是在使用Spring框架创建对象时,动态的将其所依赖的对象注入到Bean组件中。依赖注入通常有两种实现方式,一种是构造方法注入,另一种是属性setter方法注入。这两种实现方式具体介绍如下。

构造方法注入

         构造方法注入是指Spring容器调用构造方法注入被依赖的实例,构造方法可以是有参的或者是无参的。Spring在读取配置信息后,会通过反射方式调用实例的构造方法,如果是有参构造方法,可以在构造方法中传入所需的参数值,最后创建类对象。

下面通过案例演示构造方法注入的实现,具体步骤如下。

        编写用户类:新建User1类,在User1类中定义id、name和password三个属性。

public class User1 {

  private int id;   private String name;   private String password;

  public User1(int id, String name, String password){

      this.id=id; this.name=name;

      this.password=password; }

  public String toString(){

      return "id="+id+",name="+name+",password="+password;

  }}

获取Bean的配置信息:创建applicationContext-User.xml文件,在该文件中添加User1类的配置信息。

<bean id="user1" class="com.mac.User1">

        <constructor-arg name="id" value="1">

        </constructor-arg>

        <constructor-arg name="name" value="张三">

        </constructor-arg>

        <constructor-arg name="password" value="123"></constructor-arg>

</bean>

<constructor-arg>元素

  一个<constructor-arg>元素表示构造方法的一个参数,且定义时不区分顺序,只需要通过<constructor-arg>元素的name属性指定参数即可。<constructor-arg>元素还提供了type属性类指定参数的类型,避免字符串和基本数据类型的混淆。

编写测试类:

        创建测试类TestUser1,用于测试依赖注入的结果。

public class TestUser1 {

    public static void main(String[] args)throws Exception{

        //加载applicationContext.xml配置

        ApplicationContext applicationContext=new 

        ClassPathXmlApplicationContext("applicationContext-User.xml");

        //获取配置中的User1实例

        User1 user1=applicationContext.getBean("user1", User1.class);

        System.out.println(user1);

    }

}

属性setter方法注入

        属性setter方法注入是Spring最主流的注入方法,这种注入方法简单、直观,它是在被注入的类中声明一个setter方法,通过setter方法的参数注入对应的值。

下面通过案例演示属性setter方法注入的实现,具体步骤如下。

编写用户类:

        新建User2类,在User2类中定义id、name和password三个属性。

public class User2 {
    private int id;
    private String name;
    private String password;
    public void setId(int id){
        this.id=id;
    }
    public void setName(String name){
        this.name=name;
    }
    public void setPassword(String password){
        this.password=password;
    }
    public String toString(){
        return "id="+id+",name="+name+",password="+password;
    }
}

获取Bean的配置信息:创建applicationContext-User2.xml文件,并在该文件的bean元素中添加User2类的配置信息。

编写测试类:创建测试类TestUser2,用于测试依赖注入的结果。

public class TestUser2 {

    public static void main(String[] args)throws Exception {

        //加载applicationContext.xml配置

        ApplicationContext applicationContext = new 

        ClassPathXmlApplicationContext("applicationContext-User2.xml");

        //获取配置中的User2实例

        User2 user2 = applicationContext.getBean("user2", User2.class);

        System.out.println(user2);

}}

四、依赖注入的应用

下面以属性setter方法注入为例,实现一个简单的登录验证。具体实现步骤如下所示。

(1)编写DAO层:创建接口UserDao.java,在UserDao.java接口中添加方法login(),用于实现登录功能。

public interface UserDao {

    public boolean login(String name,String password);

}

(2)编写DAO层的实现类:创建UserDao接口的实现类UserDaoImpl,在UserDaoImpl类中实现login()方法。

public class UserDaoImpl implements UserDao {

    @Override

    public boolean login(String name, String password) {

        if (name.equals(“张三”)&&password.equals(“123”)){ 

return true;

        }

        return false;

    }

}

(1)编写Service层:新建service包,在service包下创建接口UserService.java,在接口中添加方法login()。

public interface UserService {

    public boolean login(String name,String password);

}

(2)编写Service层实现类:创建UserService接口的实现类UserServiceImpl,在UserServiceImpl类中实现login()方法。

public class UserServiceImpl implements UserService {

    UserDao userDao;

    public void setUserDao(UserDaouserDao)

        { this.userDao=userDao; }

    @Override

    public boolean login(String name, String password) {

        return userDao.login(name,password);

    }

}

(3)编写applicationContext.xml配置文件:使用<bean>元素添加创建的UserDaoImpl类和UserServiceImpl类的实例,并配置其相关属性。

<bean id="userDao" class="com.mac.dao.impl.UserDaoImpl"></bean>

<bean id=“userService”class="com.mac.service.impl

.UserServiceImpl">

<property name="userDao" ref="userDao">

        </property>

</bean>

(4)编写测试类:在com.mac包中新建测试类TestSpring。

public class TestSpring {

    public static void main(String[] args) {

        // 加载applicationContext.xml配置

        ApplicationContext applicationContext=new 

        ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService=(UserService) // 获取配置中的UserService实例

        applicationContext.getBean("userService");

        boolean flag =userService.login("张三","123");

        if (flag) { System.out.println("登录成功");

        } else { System.out.println(“登录失败"); }

}}

おすすめ

転載: blog.csdn.net/W_Fe5/article/details/131663444