Spring-IOC中Set和构造器注入

该文章展示了如何创建一个Maven工程,配置pom.xml文件引入Spring和日志库依赖。在代码中,使用了SLF4J进行日志记录,创建了UserDao和VipDao类,并在CostomerSercice中通过构造器实现了依赖注入。同时,展示了不同的构造函数注入方式及bean.xml配置文件中的设置。测试类验证了依赖注入的正确性。
摘要由CSDN通过智能技术生成

新建Maven工程

修改pom文件

<?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6     <groupId>com.powernode</groupId>
 7     <artifactId>spring6-002-dependency-injection</artifactId>
 8     <version>1.0-SNAPSHOT</version>
 9     <packaging>jar</packaging>
10 
11     <!--    依赖-->
12     <dependencies>
13         <dependency>
14             <groupId>org.springframework</groupId>
15             <artifactId>spring-context</artifactId>
16             <version>5.3.23</version>
17         </dependency>
18 
19         <dependency>
20             <groupId>junit</groupId>
21             <artifactId>junit</artifactId>
22             <version>4.13.2</version>
23             <scope>test</scope>
24         </dependency>
25         <!--log4j2的依赖-->
26         <dependency>
27             <groupId>org.apache.logging.log4j</groupId>
28             <artifactId>log4j-core</artifactId>
29             <version>2.19.0</version>
30         </dependency>
31         <dependency>
32             <groupId>org.apache.logging.log4j</groupId>
33             <artifactId>log4j-slf4j2-impl</artifactId>
34             <version>2.19.0</version>
35         </dependency>
36 
37     </dependencies>
38     <properties>
39         <maven.compiler.source>17</maven.compiler.source>
40         <maven.compiler.target>17</maven.compiler.target>
41     </properties>
42 
43 
44 </project>

UserDao.java

package com.lps.dao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * ClassName: UserDao
 * Description:
 * Date: 2022/11/21 16:45
 * <author>          <time>          <version>          <desc>
 * 刘品水         2022/11/21 16:45     @Version 1.0      描述
 */
public class UserDao {
    public static final Logger LOGGER=LoggerFactory.getLogger(UserDao.class);

    public void insert(){
//        System.out.println("数据库正在保存用户信息。。。。");
        LOGGER.info("数据库正在保存用户信息。。。。");
    }

}

VipDao.java

package com.lps.dao;

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

/**
 * ClassName: vipDao
 * Description:
 * Date: 2022/11/21 17:16
 * <author>          <time>          <version>          <desc>
 * 刘品水         2022/11/21 17:16     @Version 1.0      描述
 */
public class VipDao {
    public static final Logger LOGGER= LoggerFactory.getLogger(UserDao.class);

    public void insert(){
//        System.out.println("数据库正在保存用户信息。。。。");
        LOGGER.info("高级会员正在保存用户信息。。。。");
    }
}

CostomerSercice.java

package com.lps.service;

import com.lps.dao.UserDao;
import com.lps.dao.VipDao;

/**
 * ClassName: CostomerSercice
 * Description:
 * Date: 2022/11/21 17:35
 * <author>          <time>          <version>          <desc>
 * 刘品水         2022/11/21 17:35     @Version 1.0      描述
 */
public class CostomerSercice {
    private UserDao userDao;
    private VipDao vipDao;

    public CostomerSercice(UserDao userDao, VipDao vipDao) {
        this.userDao = userDao;
        this.vipDao = vipDao;
    }

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

UserService.java

package com.lps.service;

import com.lps.dao.UserDao;
import com.lps.dao.VipDao;

/**
 * ClassName: UserService
 * Description:
 * Date: 2022/11/21 16:48
 * <author>          <time>          <version>          <desc>
 * 刘品水         2022/11/21 16:48     @Version 1.0      描述
 */
public class UserService {
    private UserDao userDao;
    private VipDao vipDao;

    public void setVIP(VipDao vipDao){
        this.vipDao=vipDao;
    }


    //为了显示差别 bane属性为:set方法的方法名去掉set 然后剩下单词的首字母变小写 为了展示出来set方法名我选择为setLpsHHH

    public void setLpsHHH(UserDao ud) {
        this.userDao = ud;
    }
//正常用ait+insert直接生成的就很好了 符合规范了
   /* public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }*/

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

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


    <bean id="userDao" class="com.lps.dao.UserDao"></bean>
    <bean id="vipDao" class="com.lps.dao.VipDao"></bean>

    <bean id="costomerSerciceBean1" class="com.lps.service.CostomerSercice">
        <constructor-arg index="0" ref="userDao"></constructor-arg>
        <constructor-arg index="1" ref="vipDao"></constructor-arg>
    </bean>

    <bean id="costomerSerciceBean2" class="com.lps.service.CostomerSercice">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
        <constructor-arg name="vipDao" ref="vipDao"></constructor-arg>
    </bean>

    <bean id="costomerSerciceBean3" class="com.lps.service.CostomerSercice">
        <constructor-arg ref="userDao"></constructor-arg>
        <constructor-arg ref="vipDao"></constructor-arg>
    </bean>
</beans>

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <loggers>
        <!--
            level指定日志级别,从低到高的优先级:
                ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
        -->
        <root level="DEBUG">
            <appender-ref ref="spring6log"/>
        </root>
    </loggers>

    <appenders>
        <!--输出日志信息到控制台-->
        <console name="spring6log" target="SYSTEM_OUT">
            <!--控制日志输出的格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
        </console>
    </appenders>

</configuration>

spring.xml

实现原理:

通过property标签获取到属性名:userDao

通过属性名推断出set方法名:setUserDao

通过反射机制调用setUserDao()方法给属性赋值

property标签的name是属性名。

property标签的ref是要注入的bean对象的id。(通过ref属性来完成bean的装配,这是bean最简单的一种装配方式。装配指的是:创建系统组件之间关联的动作)

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

    <bean id="userDaoBean" class="com.lps.dao.UserDao"></bean>

    <bean id="userServiceBean" class="com.lps.service.UserService">
<!--        当需要spring调用对应的set方法 需要配置property属性-->
<!--        bane属性为:set方法的方法名去掉set 然后剩下单词的首字母变小写 为了展示出来set方法名我选择为setLpsHHH-->
<!--        ref翻译为引用 reference 后面指定要注入的bean的id-->
        <property name="lpsHHH" ref="userDaoBean"></property>
<!--        <property name="userDao" ref="userDaoBean"></property>
            建议别为难自己 直接用生成的更好 这里只是为了巩固记忆
-->
        <property name="VIP" ref="vipDaoBean"></property>
    </bean>


    <bean name="vipDaoBean" class="com.lps.dao.VipDao"></bean>


</beans>
通过测试看到程序仍然可以正常执行,说明property标签的name是:setUserDao()方法名演变得到的。演变的规律是:
  • setUsername() 演变为 username
  • setPassword() 演变为 password
  • setUserDao() 演变为 userDao
  • setHaHaHa() 演变为 haHaHa
另外,对于property标签来说,ref属性也可以采用标签的方式,但使用ref属性是多数的:
总结:set注入的核心实现原理:通过反射机制调用set方法来给属性赋值,让两个对象之间产生关系。

测试类

package com.lps;

import com.lps.dao.VipDao;
import com.lps.service.CostomerSercice;
import com.lps.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * ClassName: test
 * Description:
 * Date: 2022/11/21 16:56
 * <author>          <time>          <version>          <desc>
 * 刘品水         2022/11/21 16:56     @Version 1.0      描述
 */
public class test {
    @Test
    public void testConstructor(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        CostomerSercice contextBean = context.getBean("costomerSerciceBean1", CostomerSercice.class);
        contextBean.save();
        System.out.println("=========");
        CostomerSercice contextBean1 = context.getBean("costomerSerciceBean2", CostomerSercice.class);
        contextBean1.save();
        System.out.println("--------");
        CostomerSercice contextBean2 = context.getBean("costomerSerciceBean3", CostomerSercice.class);
        contextBean2.save();
    }
    @Test
    public void testIoC01(){
        ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
        UserService userServiceBean = context.getBean("userServiceBean", UserService.class);
        userServiceBean.saveUser();
//        VipDao vipDaoBean = context.getBean("vipDaoBean", VipDao.class);
//        vipDaoBean.insert();
    }
}
通过测试 上述testConstructor()得知,通过构造方法注入的时候:
  • 可以通过下标
  • 可以通过参数名
  • 也可以不指定下标和参数名,可以类型自动推断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值