【Spring】IoC常用的三种DI注入方式

Spring IoC 通过 DI 注入的三种常用方式

  1. 构造器注入
  2. set注入
  3. 注解注入(自动注入)

注入方式不止这几种,这里主要列举常用的三种注入方式整理及个人学习总结, 其他注入方式并未列出,如有侵权或错误,请指认留言,在此表示感谢!

01_构造方法注入

  • 使用类中的构造函数,给成员变量(简单类型、javaBean)赋值

1. 提供对应的构造方法,如下:

public class User {
	 /*
     * 配置构造方法的参数
     * */
    private int id;
    private String username;
    private String password;

    /*
     * 提供对应的构造方法
     * */
    public User() {}
    public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    /*
    * 打印输出
    * */
    public void Test(){
        System.out.println("id="+id);
        System.out.println("username="+username);
        System.out.println("password="+password);
    }
}

2. spring.xml配置文件

 <!--构造器-->
    <bean id="user" class="cn.tzgod.bean.User">
        <constructor-arg name="id"		 value="1"/>
        <constructor-arg name="username" value="tzgod"/>
        <constructor-arg name="password" value="123"/>
    </bean>
  • 测试代码
  		/*
        *构造方法注入
        * */
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user = applicationContext.getBean(User.class,"user");
        user.Test();
        /*  
        * 输出结果:
        * id=1
		* username=tzgod
		* password=123
        * */
  • 当出现了重载构造方法,并且仅仅是参数的顺序不同,那么配置的时候需要配置index来确认顺序type属性表示参数的类型
 	 /*
     * 提供对应的构造方法
     * */
    public User() {}
    public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
    /*
     * 提供重载构造方法
     * */
    public User(String password, String username ,int id ) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

2. spring.xml配置文件

	 <!--使用重载之前的构造方法-->
    <bean id="user" class="cn.tzgod.bean.User">
        <constructor-arg name="id"		 value="1"	      index="0"/>
        <constructor-arg name="username" value="tzgod"	  index="1"/>
        <constructor-arg name="password" value="123"	  index="2"/>
    </bean>
    <!--使用重载的构造方法-->
    <bean id="user" class="cn.tzgod.bean.User">
        <constructor-arg name="id"		 value="1"	  	  index="2"/>
        <constructor-arg name="username" value="tzgod"    index="1"/>
        <constructor-arg name="password" value="123" 	  index="0"/>
    </bean>

02_Set方法注入

  • 在对某个类中提供所需对象属性时,是通过其提供的set方法注入给成员变量(简单类型、javaBean)赋值,而不是直接通过属性名称注入的
  1. 创建一个set方法,如下:
public class User {
 	/*
     * 配置构造方法的参数
     * */
    private int id;
    private String username;
    private String password;
    
     /**
     * 通过Set方法完成依赖注入
     */
    public void setId(int id){
        this.id = id ;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    /**
     * 提供toString方法
     */
    @Override
    public String toString() {
        return "toString{" +
                "id='" + id + '\'' +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
  1. 配置spring.xml注入

注入的值有两种方式:

  1. 一种叫value,表示基本数据类型和字符串的设置。
  2. 一种叫ref,表示引用其他对象(构造方法中也可以使用)
  • value方式
    <!--配置spring.xml-->
    <bean id="set" class="cn.tzgod.bean.User" >
        <!--通过set方法注入-->
        <property name="id"		   value="1"/>
        <property name="username"  value="tzgod"/>
        <property name="password"  value="123"/>
    </bean>
		/*
         *测试方法
         * */
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user =  applicationContext.getBean(User.class,"set");
        System.out.println(user);
        /*
         *输出结果:
         *toString{id='1'username='tzgod', password='123'}
         * */
  • ref方式
/*
 *创建User对象
 */
public class Users {
    private User user;

    public void setUser(User user) {
        this.user = user;
    }
    /*输出user*/
    public void say(){
        System.out.println("User:" + user );
    }
}
    <!--配置spring.xml-->
	<bean id="set" class="cn.tzgod.bean.User" >
        <!--通过set方法注入-->
        <property name="id"		   value="1"/>
        <property name="username"  value="tzgod"/>
        <property name="password"  value="123"/>
    </bean>
    <bean id="user2" class="cn.tzgod.bean.Users" >
        <!--通过set方法注入-->
        <property name="user" ref="set"></property>
    </bean>
	/*
	*测试方法
	* */
      ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Users users =  applicationContext.getBean(Users.class,"user2");
        users.say();
         /*
         *输出结果:
         *User:toString{id='1'username='tzgod', password='123'}
         * */
        

03_注解注入

由于spring的核心就是一个工厂,pring利用IoC+工厂模式这一套解耦的设计理念,用Spring对象工厂+DI进行自动注入,这里只简单的介绍下注解的作用

  • 主要有四种注解可以注册bean,作用于类上,用来表示将当前的类交给Spring进行管理(创建对象、注入对象),很多时候可以随便用 (不建议)。

@Controller : 一般用在控制器上
@Service : 一般用在业务层
@Repository : 一般用在DAO上
@Component : 一般用在其他任何位置(默认ID是当前类的首字母小写,同时也可以在@Component注解的参数中指定ID)

  • 主要以以下注解进行自动装配
  • @Autowired : 作用于方法上,用来表示当前方法需要被注入一个对象 , 在所有需要注入的属性上加上@Autowired注解,甚至可以不写set方法
  • @Resource : 作用于方法上, 优先通过byName查找属性名相同的bean的名字,找不到才从byType查找属性相同的bean的属性
  • @Bean : 作用于方法上,用来表示此方法提供一个对象
  • @Qualifier : 作用于方法上,用来表示当前注入一个指定名称的对象,当同类型的对象有多个,并且了变量的名称不匹配任何的对象,则可以通过Qualifier注解指定注入哪个对象。一般情况Qualifier和Autowired是配合使用。
  • @Configuration : 作用于类上,用来表示当前类为Spring的初始化配置类(入口类)
  • @ComponentScan : 作用于类上,一般和Configuration 一起使用,用来表示Spring需要管理的类在哪一个包下
  • spring中使用注解
    在Spring配置文件中添加扫描的路径:
<!-- 扫描的路径为项目路径 -->
<context:component-scan base-package="cn.tzgod"></context:component-scan>

实际上开发的时候自己编写的类一般用注解的方式注册类,用@Autowired描述依赖进行注入也可以用@Resource自动注入功能,两者之间没什么太大差别,主要区别就是@Autowired是默认按照类型装配的 @Resource默认是按照名称装配的

附:

_复杂类型注入

  • 对于数组,List或Set类型,当元素只有一个时,可以直接使用value或ref,
  • 当有多个元素时,set,array,list标签可以互换,用的也是set方法注入的方式,只不过变量的数据类型都是集合。
  • Map和Properties才需要单独特殊处理。
public class MyData {
    private Object [] arr;
    private List list;
    private Map map;
    private Set set;
    private Properties prop;

    public void setArr(Object[] arr) {
        this.arr = arr;
    }

    public void setList(List list) {
        this.list = list;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public void setSet(Set set) {
        this.set = set;
    }

    public void setProp(Properties prop) {
        this.prop = prop;
    }
    @Override
    public String toString() {
        return "MyData{" +
                "arr=" + Arrays.toString(arr) +
                ", list=" + list +
                ", map=" + map +
                ", set=" + set +
                ", prop=" + prop +
                '}';
    }
}
<bean id="myData" class="cn.tzgod.bean.MyData">
    <property name="arr">
        <array>
            <value>arr1</value>
            <value>arr2</value>
        <array>
    </property>
    
    <property name="list">
        <list>
            <value>list1</value>
            <value>list2</value>
        <list>
    </property>
    
    <property name="map">
        <map>
            <entry key="a"  value="1111" value-type="java.lang.Integer"></entry>
            <entry key="c"  value="mapc" ></entry>
        </map>
    </property>
    
    <property name="set">
        <set>
            <value>set1</value>
            <value>set2</value>
        </set>
    </property>

    <property name="prop">
        <props>
            <prop key="aaa">prop1</prop>
            <prop key="bbb">prop2</prop>
        </props>
    </property>
</bean>

_p空间和spEL注入

p空间:
是注入是一种简写的办法
  • 首先需要引入p空间,在配置文件中添加p空间的引入:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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="set" class="cn.tzgod.bean.User" >
        <property name="id"		   value="1"/>
        <property name="username"  value="tzgod"/>
        <property name="password"  value="123"/>
    </bean>
<!--上面的写法简写为下面的写法:-->
<bean id="set" class="cn.tzgod.bean.User" 
p:id="1" p:username="tzgod" p:password="123" >

</bean>
spEL:
spEL是指在引用时使用表达式。#{}表示引用其他对象,${}表示引用其他文件中的内容。
  • 添加一个 . properties配置文件 : myconfig . properties
c.id=1
c.username=tzgod
c.password=123
  • 配置文件中如下配置:
<bean id="c" class="cn.tzgod.bean.User">
        <property name="id"		   value="1"/>
        <property name="username"  value="tzgod"/>
        <property name="password"  value="123"/>
    </bean>

<!-- 下面表示表示引用properties配置文件 -->
<context:property-placeholder location="classpath:myconfig.properties"></context:property-placeholder>

<bean id="set" class="cn.tzgod.bean.User">
    <property name="id"		   value="#{c.id}"/>
    <property name="username"  value="#{c.username}"/>
    <property name="password"  value="#{c.password}"/>
</bean>

_多配置文件加载

  • 在主配置文件(spring.xml)中导入子配置文件
<import resource="spring01.xml"/>
<import resource="spring02.xml"/>
<import resource="spring03.xml"/>
格式一:
加载ApplicatioContext对象时需要加载主配置文件即可
	ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
格式二:
一次性加载多个配置文件(可变参数对象格式)
	ApplicationContext ctx = new ClassPathXmlApplicationContext(
	"spring01.xml","spring02.xml","spring03.xml");
格式三:
一次性加载多个配置文件(数组对象格式)
	ApplicationContext ctx = new ClassPathXmlApplicationContext(
	new String[]{"spring01.xml","spring02.xml","spring03.xml"})

注意事项

  • 配置冲突问题,后生效的配置覆盖之前的配置!
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring框架中,IOC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)是两个重要的概念。 IOC是一种设计原则,它反转了传统的程序设计中对象的创建和依赖关系的管理方式。传统方式中,对象的创建和依赖关系是由程序代码直接控制的,而在IOC中,对象的创建和依赖关系的管理交给了容器来完成。应用程序通过描述对象之间的依赖关系,由容器负责创建对象、维护对象的生命周期,并将所需的对象注入到需要它们的地方。 DIIOC的一种具体实现方式。它通过将对象之间的依赖关系定义在配置文件中或通过注解来描述,容器会根据这些配置信息自动创建对象,并将依赖关系注入到对象中。通过DI,我们可以将对象之间的耦合度降低,提高代码的可测试性、可维护性和可扩展性。 在Spring框架中,我们可以使用XML配置文件、Java配置类或注解来描述对象之间的依赖关系。Spring容器会根据这些配置信息实例化对象,并将依赖关系自动注入到对象中。这样,我们就可以通过IOC容器来管理对象的创建和依赖关系,而不需要在代码中直接进行对象的创建和依赖关系的维护。 总结来说,IOCDISpring框架中的核心概念,通过将对象的创建和依赖关系的管理交给容器来完成,可以降低代码的耦合度,提高代码的可测试性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值