IOC控制反转,DI依赖注入

本文深入解析Spring框架中的控制反转(IoC)与依赖注入(DI)概念,阐述其工作原理,包括设值注入、构造注入及自动装配等配置方式,并介绍基于注解的配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.1、IOC

IOC分别控制反转和依赖注入。

所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

控制反转(IOC:Inversion of Control):将对象的实例化交由spring来负责创建,说白了就是在xml中配置对象的bean实例。

依赖注入(DI: Dependency injection):在创建对象实例时,为这个对象注入属性值或其它对象实例。

1.1.1、依赖注入方式:(配置版)
  1. 设值注入:通过setXxx()方法注入(个人推荐:可以灵活组合)

    1、需要使用setXxx()方法,在application.xml文件中使用

    UserServiceImpl.java中

    public class UserServiceImpl implements UserService {
    //	private UserDao userDao=new UserDaoImpl();//死代码
    	private UserDao userDao;
    	private String name;
    	private String sex;
    	
    	public void setUserDao(UserDao userDao) {
    		this.userDao = userDao;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public UserServiceImpl() {
    	}
    
    	public UserServiceImpl(UserDao userDao, String name,String sex) {
    		this.userDao = userDao;
    		this.name = name;
    		this.sex=sex;
    	}
    
    	@Override
    	public int addUser(User entity) {
    		System.out.println("name:"+name+",sex:"+sex);
    		return userDao.addUser(entity);
    	}
    
    }
    
    

    application.xml中:

   <bean id="userService" class="com.ioc.conf.service.impl.UserServiceImpl">
       	<!-- 设值注入 -->
       	<property name="userDao" ref="userDao" />
       	<property name="name" value="张三" />
       	
    </bean>
  1. 构造注入:通过构造方法注入

    UserServiceImpl.java中需要提供构造函数

    application.xml中

    <bean id="userService" class="com.ioc.conf.service.impl.UserServiceImpl">
        	<!-- 构造注入 -->
        	<!-- index:配置对应构造参数的位置,从0开始
        	<constructor-arg index="0" ref="userDao" />
        	<constructor-arg index="2" value="男" />
        	<constructor-arg index="1" value="张三" />
        	 -->
        </bean>
    
  2. p命名空间注入:

    第一步:需要p命名空间的声明

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

    第二步:使用

    <!-- p命名空间注入 -->
    <!-- 
         p:属性名:配置的常量值
         p:属性名-ref:配置引用类型的名称
         -->
    <bean id="country1" class="com.ioc.conf.entity.Country"
          p:name="中国" />
    
    <bean id="user1" class="com.ioc.conf.entity.User"
          p:id="1"
          p:loginName="admin"
          p:password="123"
          p:country-ref="country1" />
    
1.1.2、singleton和prototype

singleton:单例(默认值)

prototype:多例

<bean id="userService" class="com.ioc.conf.service.impl.UserServiceImpl"
    	scope="prototype">
</bean>    
1.1.3、自动装配

spring提供了4种自动装配类型

取值说明
no默认值,spring默认不进行自动装配,必须显示指定依赖对象
byType根据属性类型自动装配,如果找到多个报错,只有找到唯一的那个,才会自动注入。如果找不到,什么也不做。
byName根据属性名称自动装配,找到bean的id值与属性名相同会自动注入。如果找不到,什么也不做。
constructor和byType类似,不过它针对的构造方法。如果找到1个 bean和构造方法的参数类型相匹配,则通过构造注入,否则什么也不做。
<!-- 第一种:在每个bean中通过autowire属性进行配置 -->
<bean id="userService2" class="com.ioc.conf.service.impl.UserServiceImpl"
    	scope="prototype" autowire="constructor">
    	<!-- <property name="userDao" ref="userDao" /> -->
    	<!-- <property name="name" value="张三" /> -->
</bean>	

<!-- 第二种:直接在<beans>标签上配置default-autowire="default“ -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
       	   http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"
           default-autowire="default">
</beans>    

注意:不推荐使用,自动装配使得配置文件可以非常简洁,但同时也造成类型之间的依赖关系不明确,容易引发一些潜在的问题,在实际项目中需要谨慎使用。

1.1.4、基于注解的配置
  1. @Component:代表组件,表示1个bean实例
  2. @Controller:用于标注控制层
  3. @Service:用于标注业务层
  4. @Repository:用于标注模型层
  5. @Autowired:自动注入,byType(属于spring的注解)
  6. @Resource:自动注入,byName(属于j2ee的注解)
  7. @Qualifier:根据属性名注入:byName
  8. @Scope:配置singleton和prototype。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值