Spring核心知识点系列5--Spring配置文件之bean的依赖注入

发布于:2023-01-06 ⋅ 阅读:(2312) ⋅ 点赞:(2)

1. 依赖注入的概念

当某个java对象(调用者)调用另个一java对象(被调用者,即被依赖对象)时,在传统的模式下,调用者内部通常会采用“new 被调用者”的方式来创建被调用者的实例对象,然后由该实例对象调用它的方法。
这种方式会导致调用者与被调用者之间的耦合性增加,不利于项目的维护与升级。而Spring框架完美的解决了这个问题,对象的实例不在由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不再是由调用者的程序代码控制,这样控制权由应用代码转移到了Spring容器,反生了控制反转,这就是Spring里面的控制反转(IoC)。
由Spring容器负责将被调用者的对象赋值给调用者的成员变量,这一行为就被称为依赖注入
文字枯燥难以理解,下面结合一个实例来理解上面的含义:

2. 传统模式的依赖关系

创建UserDao,UserDao内部有一个save()方法

public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("UserDaoImpl of save running");
    }
}

创建 UserService,UserService 的save()方法内部在调用 UserDao的save() 方法

public class UserServiceImpl implements UserService {
	
	@Override
	public void save() {
		UserDaoImpl userDao=new UserDaoImpl();
		userDao.save();
	}
}

将 UserServiceImpl 的创建权交给 Spring

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl"/>

从 Spring 容器中获得 UserService 进行操作

  @org.junit.Test
    public void test(){
        //获取Spring容器
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean对象
        UserService userService = (UserService) applicationContext.getBean("userService");
        //bean对象调用方法
        userService.save();
        
    }

可见,传统模式下调用者userservice和被调用者userDao之间依赖关系,由调用者userService内部的应用程序代码控制,,这就导致了调用者和被调用者的都合度增加。利用Spring的依赖注入就可以解决掉这个弊端。

3. 依赖注入的实现式

3.1setter方式的依赖注入实现

setter方式注入:指Spring容器使用setter注入被依赖的实例。通过调用无参构造器或者无参静态工厂实例化bean后调用set方法实现依赖的注入
需求:使用依赖注入的方式实现在UserService的save方法里面调用userDao的save方法

创建UserDao,UserDao内部有一个save()方法

public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("UserDaoImpl of save running");
    }
}

创建 UserService,UserService 的save()方法内部在调用 UserDao的save() 方法

public class UserServiceImpl implements UserService {
    //声明userDao属性
    private UserDaoImpl userDao;
    //添加userDao属性的set方法,用于实现依赖注入
    public void setUserDao(UserDaoImpl userDao) {
        this.userDao = userDao;
    }

    @Override
    public void save() {
        //调用userDao的方法
        userDao.save();
    }
}

将对象的创建权交给spring容器,并有Spring容器实现依赖注入

    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
        <bean id="userService" class="com.itheima.dao.impl.UserServiceImpl">
            <property name="userDao" ref="userDao"/>
        </bean>

从 Spring 容器中获得 UserService 进行操作

  @org.junit.Test
    public void test(){
        //获取Spring容器
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean对象
        UserService userService = (UserService) applicationContext.getBean("userService");
        //bean对象调用方法
        userService.save();
        
    }

set方式的命名空间引入
P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
首先,需要引入P命名空间:

xmlns:p="http://www.springframework.org/schema/p"

其次,需要修改注入方式

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" p:userDaoref="userDao"/

3.2有参构造函数实现依赖注入

创建UserDao,创建save()方法

public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("UserDaoImpl of save running");
    }
}

创建UserService,并创建userDao属性和save()方法


public class UserServiceImpl implements UserService {
  
//    有参构造方法注入参数
   private UserDaoImpl userDao;

    public UserServiceImpl(UserDaoImpl userDao) {
        this.userDao = userDao;
        System.out.println("UserService的有参构造函数被调用了");
    }
    
    @Override
    public void save() {
        //调用userDao的方法
        userDao.save();
    }
}

从 Spring 容器中获得 UserService 进行操作

  @org.junit.Test
    public void test(){
        //获取Spring容器
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean对象
        UserService userService = (UserService) applicationContext.getBean("userService");
        //bean对象调用方法
        userService.save();
        
    }
 <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
    <bean id="userService" class="com.itheima.dao.impl.UserServiceImpl">
        <constructor-arg name="userDao" ref="userDao"/>
    </bean>

看结果:
在这里插入图片描述
还有一点是使用有参构造来注入依赖的时候,bean实例是通过有参构造函数来创建的。


网站公告

今日签到

点亮在社区的每一天
去签到