Spring实现IoC:依赖注入/构造注入

● 控制反转,反转的是什么?
○ 将对象的创建权利交出去,交给第三方容器负责。
○ 将对象和对象之间关系的维护权交出去,交给第三方容器负责。
● 控制反转这种思想如何实现呢?
○ DI(Dependency Injection):依赖注入

依赖注入

依赖注入:
● 依赖指的是对象和对象之间的关联关系。
● 注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。
依赖注入常见的实现方式包括两种:
● 第一种:set注入
● 第二种:构造注入

在第一个程序中,尽管通过Spring容器创建并管理了一个对象,但以第一章为例,表现层创建了一个Userservice控制层对象:

private Userservice userService = new UserServiceImp();

而在第二章中

   ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
   Object userBean = applicationContext.getBean("userDaoBean");
   //这两行代码完成了"new UserServiceImp"的功能,还剩另一半功能,即将容器创建的对象赋值给任意层的对象,将这个具体的张三放到工作岗位上,这另一半就是依赖注入.

set注入

set注入,基于set方法实现的,底层会通过反射机制调用属性对应的set方法然后给属性赋值。这种方式要求属性必须对外提供set方法。

新建模块:spring6-002-dependency-injection
本例中,方便起见,不再采用接口-实现类的方式,而是每一层直接定义一个抽象类.


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.powernodegroupId>
    <artifactId>spring6-002-dependency-injectionartifactId>
    <version>1.0-SNAPSHOTversion>
    <packaging>jarpackaging>

    <repositories>
        <repository>
            <id>repository.spring.milestoneid>
            <name>Spring Milestone Repositoryname>
            <url>https://repo.spring.io/milestoneurl>
        repository>
    repositories>

    <dependencies>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>6.0.0-M2version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.13.2version>
            <scope>testscope>
        dependency>
         <dependency>
            <groupId>org.apache.logging.log4jgroupId>
            <artifactId>log4j-slf4j2-implartifactId>
            <version>2.19.0version>
        dependency>
    dependencies>

    <properties>
        <maven.compiler.source>17maven.compiler.source>
        <maven.compiler.target>17maven.compiler.target>
    properties>

project>

结构
Spring实现IoC:依赖注入/构造注入_第1张图片

resources-spring.xml

<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 http://www.springframework.org/schema/beans/spring-beans.xsd">


       <bean id="userDaoBean" class="com.sunsplanter.spring6.dao.UserDao"/>
       <bean id="userServiceBean" class="com.sunsplanter.spring6.service.UserService">

              <property name="mySQLUserDao" ref="userDaoBean"/>
       bean>

beans>
package com.sunsplanter.spring6.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserDao {
    //log4j2可以选择输出到控制台/文件,还可以选择各种输出等级
    private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
    public void insert(){
        logger.info("saving...");
    }
}
package com.sunsplanter.spring6.service;

import com.sunsplanter.spring6.dao.UserDao;

public class UserService {
//创建一个持久层对象,但这次不再依赖调用下层创建,而是用Spring容器创建,并且用Set依赖注入的方法进行赋值
    private UserDao userDao;
//

    //ALT+insert用Idea生成set方法
//    public void setUserDao(UserDao userDao) {
//        this.userDao = userDao;
//    }

    //自定义set方法
    //要求1:必须是set开始
    //要求2:set哪个对象(注入哪个对象),就在spring.xml中找到对应管理该对象的标签,在bean标签中增加一个子标签
    //该子标签的name属性必须满足规范:去掉该set方法的set,剩下单词采用驼峰命名法,即mySySQLUserDao
    public void setMySQLUserDao(UserDao xyz){
        this.userDao = xyz;
    }

    public void saveuser(){
        userDao.insert();
    }
}
package com.sunsplanter.spring6.test;

import com.sunsplanter.spring6.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDITest {
    @Test
    public void testSetDI(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        UserService userService = applicationContext.getBean("userServiceBean", UserService.class);
        userService.saveuser();
    }
}

总结:set注入的核心实现原理:通过反射机制调用set方法来给属性赋值,让两个对象之间产生关系。


构造注入

核心原理:通过调用构造方法来给属性赋值。
与依赖注入的核心区别:构造注入是在对象实例化的过程中注入的.

结构为:
Spring实现IoC:依赖注入/构造注入_第2张图片
其中,Userservice,spring_dependency.xml,SpringDITest_dependency不再使用

package com.sunsplanter.spring6.service;

import com.sunsplanter.spring6.dao.UserDao;
import com.sunsplanter.spring6.dao.VipDao;

public class CustomerService {
    //先声明两个持久层的对象,然后利用spring容器构造出后,用构造方法注入
    private UserDao userDao;
    private VipDao vipDao;

    public CustomerService(UserDao userDao, VipDao vipDao) {
        //按照先后顺序,对应spring2_constructor第三个bean中0号和1号constructor标签
        this.userDao = userDao;
        this.vipDao = vipDao;
    }

    public void saveUsers(){
        userDao.insert();
        vipDao.insert();
    }
}


<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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userDaoBean" class = "com.sunsplanter.spring6.dao.UserDao"/>
    <bean id="vipDaoBean" class = "com.sunsplanter.spring6.dao.VipDao"/>
    <bean id="customerServiceBean" class = "com.sunsplanter.spring6.service.CustomerService">



        
                <constructor-arg name = "userDao" ref="userDaoBean"/>
                <constructor-arg name = "vipDao" ref="vipDaoBean"/>
    bean>
    
beans>
package com.sunsplanter.spring6.test;

import com.sunsplanter.spring6.service.CustomerService;
import com.sunsplanter.spring6.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDITest_constructor {
    @Test
    public void testConstructorDI(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring2_constructor.xml");
        CustomerService custormerService = applicationContext.getBean("customerServiceBean", CustomerService.class);
        custormerService.saveUsers();
    }
}

你可能感兴趣的:(spring,java,后端)