精华内容
下载资源
问答
  • di依赖注入
    2021-07-26 19:26:41

    本文主要介绍.NET Core(C#) Console项目中,实现DI依赖注入的方法步骤,及实现和ASP.NET Core项目一样使用ConfigureServices()方法配置服务,以及相关实现的示例代码。
    原文地址:.NET Core(C#) Console控制台项目中使用DI依赖注入(ConfigureServices)

    更多相关内容
  • 易于理解的说明, 简单明了的DEMO,从正常的编程方式,演变到依赖注入,再演变到AOP切面编程。 描述了什么是反转控制,什么是容器
  • 较为框架式的演示了DI服务依赖注入 适用于熟悉C#中的继承,基本的Core命令使用等. 该示例演示了以服务器集群为背景的各种业务的依赖注入. 示例来自于B站杨中科老师的.NET Core(6.0)教学.
  • java Spring DI依赖注入.rar
  • 7.1 DI依赖注入1

    2022-08-08 23:17:47
    除了构造函数注入(ServicesCollection支持,后两个不支持),还有属性注入,方法注入//调用IZhaoxiContainer zhaoxiCont
  • 该项目实现了简单的IOC技术思想和DI依赖注入
  • DI,是dependence injection的简称,译为依赖注入,和上一篇解释的IOC控制反转思想是一个意思,IOC是用来创建对象的思想,DI依赖注入,就是在配置Spring容器(xxx.xml文件)创建对象的同时为对象注入属性值。...

    一、什么是DI

    案例工程代码下载
    DI,是dependence injection的简称,译为依赖注入,和上一篇解释的IOC控制反转思想是一个意思,IOC是用来创建对象的思想,DI依赖注入,就是在配置Spring容器(xxx.xml文件)创建对象的同时为对象注入属性值。而依赖注入的方式有5种:Setter注入(set方法注入)、interface注入(接口注入)、constructor注入(构造注入)、autowire注入(自动注入)、Annotation注入(注解注入)。

    二、5种依赖注入方式

    (一)Setter注入

    用Setter注入方式的类中必须提供set方法生效,否则会报错。我们来实现实现一下Setter注入方式:

    1.创建ClassB类,定义属性和提供set方法,重写toString方法(更改输出格式,输出属性值,也可以不重写)。
    package testspringIOCDI.id;
    import java.util.Date;
    
    /**数据bean,类ClassB
     * @author CenterLogo
     *create date :2019年4月25日 下午7:05:56
     */
    public class ClassB {
    	 private String userid;
    	 private String username;
    	 private Date hiraedate;
    	 
    	public void setUserid(String userid) {
    		this.userid = userid;
    	}
    	
    	public void setUsername(String username) {
    		this.username = username;
    	}
    
    	public void setHiraedate(Date hiraedate) {
    		this.hiraedate = hiraedate;
    	}
    
    	@Override
    	public String toString() {
    		return "ClassB [userid=" + userid + ", username=" + username + ", hiraedate=" + hiraedate + "]";
    	}
    	 public void method(){
    		 System.out.println("I'm classB");
    	 }
    }
    
    2.在Spring容器(我这里创建的是SpringDI.xml)中配置信息,实现Setter注入。在SpringDI中配置如下:
    <?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">
    <!-- setter注入(属性值),条件是类中必须有对应set方法 -->
           <!-- 创建classb对象 -->
    		<bean id="classb" class="testspringIOCDI.id.ClassB">
    		<!-- setter注入,给属性赋值,这里的作用是调用setUserid(10010)方法 -->
    		   <property name="userid" value="100010"></property>
    		   <property name="username">
    		     <value>Lily</value>
    		  
    		  <!-- 属性值是对象(日期对象),在property属性标签中添加gbean标签,此处 相当于classb.setHiredate(new java.util.Date()); -->
    		   </property>
    		   <property name="hiraedate">
    		    <bean  class="java.util.Date"></bean>
    		   </property>
    		</bean>
    </beans>
    
    3.创建ClassB的测试类,用来测试是否能成功获取Setter注入后ClassB类的对象。
    package testspringIOCDI.id;
    import static org.junit.Assert.*;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * @author CenterLogo
     *create date :2019年4月25日 下午:22:43
     */
    public class DITest {
    	@Test
    	public void test() {
    		//获取上下文实例,使用ClassPathXmlApplicationContext不需要写路径,只需要写xml文件名
    		ApplicationContext context=new ClassPathXmlApplicationContext("SpringDI.xml");
    		//从容器中获取具体对象
    		ClassB cb=context.getBean("classb",ClassB.class);
    		 System.out.println(cb);
    	}
    }
    

    测试成功的结果如此下,控制台输出:

    ClassB [userid=100010, username=Lily, hiraedate=Sun Apr 28 15:46:31 CST 2019]

    (二)interface注入

    interface注入原理和Setter注入一样,只不过是类的属性定义中存在接口,我们需要在Spring容器中创建接口的实现类对象,将实现类对象赋值给接口。具体实现方式如下:

    1.创建InterfaceA接口
    //InterfaceA接口
    package testspringIOCDI.ioc;
    public interface InterfaceA {
       public String getInfo();
    	 public void method();
    }
    
    2.创建InterfaceA接口的实现类ClassA
    //创建InterfaceA的实现类
    package testspringIOCDI.ioc;
    public class ClassA implements InterfaceA {
    	public ClassA(){}
    	public String getInfo() {
    		// TODO Auto-generated method stub
    		return "企业管理系统模块:实现公告发布、修改、删除等操作";
    	}
    	 public void method(){
    		 System.out.println("I'm classA");	 
    	 }
    }
    
    3.创建ClassC,当中具有一个InterfaceA属性,并提供set方法。
    package testspringIOCDI.id;
    import testspringIOCDI.ioc.InterfaceA;
    /**
     * @author CenterLogo
     *create date :2019年4月25日 下午9:12:23
     */
    public class ClassC {
    private InterfaceA ia;
    public void setIa(InterfaceA ia) {
    	this.ia = ia;
    }
    public void mentho(){
    	System.out.println("interface注入:"+ia.getInfo());
    }
    }
    
    4.配置Spring容器(SpringDI.xml)文件,实现interface注入。
    <?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">
    		                    
    		<!-- interface注入 --><!-- 有interface属性,必须有set方法 -->
    		<bean id="classa" class="testspringIOCDI.ioc.ClassA"></bean><!-- 获取实现接口类的对象 -->
    		<bean id="classc" class="testspringIOCDI.id.ClassC"><!-- 将获取实现接口类的对象作为属性注入 -->
    		<property name="ia" ref="classa"></property>
    		</bean>
    </beans>
    
    5.创建ClassC的测试类,测试注入是否成功。
    package testspringIOCDI.id;
    import static org.junit.Assert.*;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * @author CenterLogo
     *create date :2019年4月25日 下午9:24:53
     */
    public class InterfaceTest {
    	@Test
    	public void test() {
    		ApplicationContext context=new ClassPathXmlApplicationContext("SpringDI.xml");
    		ClassC cc=(ClassC) context.getBean("classc");
    		cc.mentho();
    	}
    }
    

    测试成功的结果在控制台显示如下:

    interface注入:企业管理系统模块:实现公告发布、修改、删除等操作

    (三)constructor注入(构造注入)

    constructor注入,要想以这种方式给类注入属性,该类必须同时含有无参构造方法和有参构造方法(不需要set方法)。其原理是Spring容器会根据类的有参构造方法去给属性赋值。演示实现constructor注入如下:

    1.创建ClassB,定义属性,提供无参和有参构造。
    package testspringIOCDI.id;
    import java.util.Date;
    /**数据bean
     * @author CenterLogo
     *create date :2019年4月25日 下午7:05:56
     */
    public class ClassB {
    	 private String userid;
    	 private String username;
    	 private Date hiraedate;
    	public ClassB() {}//无参构造
    	public ClassB(String userid, String username, Date hiraedate) {//有参构造
    		super();
    		this.userid = userid;
    		this.username = username;
    		this.hiraedate = hiraedate;
    	}
    	@Override
    	public String toString() {
    		return "ClassB [userid=" + userid + ", username=" + username + ", hiraedate=" + hiraedate + "]";
    	}
    	 public void method(){
    		 System.out.println("I'm classB"); 
    	 }
    }
    
    2.在Spring容器(SpringDI.xml)文件中配置constructor注入方式,通过参数下标注入。
    <?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="date" class="java.util.Date"></bean>
    		<bean id="classbct" class="testspringIOCDI.id.ClassB">
    		  <constructor-arg index="0" value="20"/>
    		  <constructor-arg index="1" value="center"/>
    		  <constructor-arg index="2" ref="date"/>
    		</bean>  
    </beans>
    
    3.创建ClassB的测试类,测试constructor注入是否成功。
    package testspringIOCDI.id;
    import static org.junit.Assert.*;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * @author CenterLogo
     *create date :2019年4月25日 下午9:58:10
     */
    public class ConstructorTest {
    	@Test
    	public void test() {
    		ApplicationContext context=new ClassPathXmlApplicationContext("SpringDI.xml");
    		ClassB cb=(ClassB) context.getBean("classbct");
    		System.out.println(cb);
    	}
    }
    

    测试成功的结果在控制台显示如下:

    ClassB [userid=20, username=center, hiraedate=Sun Apr 28 16:27:42 CST 2019]

    (四)autowire注入(自动注入)

    autowrie注入,必须提供set方法。Spring容器可以通过类中定义的属性类(类中有属性,这个属性的类型是一个类)的类型或名字来确定用哪一个对象赋值。但是要保证容器中的类的类型必须唯一或者保证成员变量名与容器中的id必须保持一致。演示autowrie注入实现如下:

    1.创建ClassE,定义属性有ClassA类和ClassC类(已经创建好),并提供set方法。
    package testspringIOCDI.id;
    import testspringIOCDI.ioc.ClassA;
    /**
     * @author CenterLogo
     *create date :2019年4月26日 下午8:16:58
     */
    public class ClassE {
      private ClassC classc;
      private ClassA classa;
    
    public void setClassc(ClassC classc) {
    	this.classc = classc;
    }
    public void setClassa(ClassA classa) {
    	this.classa = classa;
    }
    public void  method(){
    	  classc.mentho();
    	  classa.method();
    	  System.out.println("succeed");
      }
    }
    
    2.配置Spring容器(Spring.xml)文件,采用aotuwire注入方式。
    <?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">
    		<!-- interface注入 --><!-- 有interface属性,必须有set方法 -->
    		<bean id="classa" class="testspringIOCDI.ioc.ClassA"></bean><!-- 获取实现接口类的对象 -->
    		<bean id="classc" class="testspringIOCDI.id.ClassC"><!-- 将获取实现接口类的对象作为属性引入 -->
    		<property name="ia" ref="classa"></property>
    		</bean>
    
          <!-- autowire注入 -->
           <!-- 方式一:byName 条件:classc和classa的id必须和ClassE中的成员变量名一致 -->
          <bean id="cename" class="testspringIOCDI.id.ClassE" autowire="byName"/>
          <!-- 方式二:byType 条件:容器中必须ClassA和ClassC的类型对象分别只能有一个-->
        <bean id="cetype" class="testspringIOCDI.id.ClassE" autowire="byType"/> 
    </beans>
    
    2.创建ClassE的测试类,测试autowire注入是否成成功。
    package testspringIOCDI.id;
    import static org.junit.Assert.*;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * @author CenterLogo
     *create date :2019年4月26日 下午8:29:54
     */
    public class autowireTest {
    	@Test
    	public void test() {
    		ApplicationContext context=new ClassPathXmlApplicationContext("SpringDI.xml");
    		ClassE cename=(ClassE) context.getBean("cename");
    		ClassE cetype=(ClassE) context.getBean("cetype");
    		cename.method();
    		cetype.method();
    }
    }
    

    测试成功结果在控制台输出如下:

    interface注入:企业管理系统模块:实现公告发布、修改、删除等操作
    I’m classA
    succeed
    interface注入:企业管理系统模块:实现公告发布、修改、删除等操作
    I’m classA
    succeed

    (五)annotation注入(自动注入)

    annotation注入较为简单,也使代码更为简洁,一般作为注入都首选。annotation注入需要的条件为:一是需要类提供注解方式;二是需要在Spring中开启注解和对属性类的声明。
    演示实现annotation如下:

    1.创建ClassF,定义接口InterfaceA(前提是已创建InterfaceA类和其实现类,代码详见interface注入)并提供注解。
    package testspringIOCDI.id;
    import javax.annotation.Resource;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import testspringIOCDI.ioc.InterfaceA;
    /**
     * @author CenterLogo
     *create date :2019年4月26日 下午8:58:50
     */
    public class ClassF {
    @Resource      //注解1
    private InterfaceA ia1;
    @Resource(name="classa")//注解2
    private InterfaceA ia2;
    @Autowired  //注解3
    private InterfaceA ia3;
    @Autowired  //注解四
    @Qualifier("classa")
    private InterfaceA ia4;
    public void method(){
    	System.out.println(ia1.getInfo());
    	System.out.println(ia2.getInfo());
    	System.out.println(ia3.getInfo());
    	System.out.println(ia4.getInfo());
    	System.out.println(ia1.getInfo());//只能使用接口中存在的方法
    	ia1.method();
    }
    }
    

    代码部分解释:
    (1)@Resoure 先根据容器中类的类型匹配,如果类型匹配不到,则根据名字匹配。
    (2)@Resoure(name=“classa”) 根据id名字匹配
    (3)@Autowired 自动匹配,根据类型。
    (4)@Autowired
    @Qualifier(“classa”) 根据Spring中指定的id名字自动匹配
    (5)@Resoure 是jdk自带的注解,@Autowired是Spring beans提供的注解。

    2.在Spring容器中添加context规则,开启注解,并声明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"
    		xmlns:context="http://www.springframework.org/schema/context"
    		xsi:schemaLocation="http://www.springframework.org/schema/beans
    		                    http://www.springframework.org/schema/beans/spring-beans.xsd
    		                    http://www.springframework.org/schema/context
    		                    http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- annotation注入,开启注解 -->
        <context:annotation-config/>
        
          <!-- 声明对象 -->
      <bean id="classa" class="testspringIOCDI.ioc.ClassA"></bean><!-- 获取实现接口类的对象 -->
        <bean id="classf" class="testspringIOCDI.id.ClassF" />
    </beans>
    
    3.创建ClassF测试类,测试annotation是否成功。
    package testspringIOCDI.id;
    import static org.junit.Assert.*;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * @author CenterLogo
     *create date :2019年4月26日 下午9:18:54
     */
    public class annotationTest {
    	@Test
    	public void testMethod() {
    		ApplicationContext context=new ClassPathXmlApplicationContext("SpringDI.xml");
             ClassF cf=(ClassF) context.getBean("classf");
             cf.method();
    	}
    }
    

    测试成功结果在控制太显示如下:

    企业管理系统模块:实现公告发布、修改、删除等操作
    企业管理系统模块:实现公告发布、修改、删除等操作
    企业管理系统模块:实现公告发布、修改、删除等操作
    企业管理系统模块:实现公告发布、修改、删除等操作
    企业管理系统模块:实现公告发布、修改、删除等操作
    I’m classA

    展开全文
  • Set注入 构造器注入 静态工厂注入 实例化工厂注入 案例实操 Set注入 xml配置(同时spring也提供了对于基本数据类型的set注入方式) <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=...

    Spring 实例化 bean 的方式

    • Set注入
    • 构造器注入
    • 静态工厂注入
    • 实例化工厂注入

    案例实操

    Set注入

    xml配置(同时spring也提供了对于基本数据类型的set注入方式)

    <?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.xxx.demo.UserDao"></bean>
    	<!-- setter注入 -->
    	<bean id="userService" class="com.xxx.demo.UserService">
            <!--ref是对于外部bean对象引用,与被引用的bean对象的id保持一致-->
    		<property name="userDao" ref="userDao"></property>
    	</bean>
    </beans>
    

    UserDao.java

    public class UserDao {
    	public String userLogin() {
    		return	"我是UserDao中的userLogin()的方法";
    	}
    }
    

    UserService.java

    public class UserService {
        //一定要提供属性的setter方法
    	private UserDao userDao;
    	
    	public void userlogin() {
    		String res=userDao.userLogin();
    		System.out.println(res);
    	}
    
    	public void setUserDao(UserDao userDao) {
    		this.userDao = userDao;
    	}
    }
    

    App.java

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class App {
    	public static void main(String[] args) {
    		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-config.xml");
    		UserService userService=applicationContext.getBean("userService", UserService.class);
    		userService.userlogin();
    	}
    }
    

    构造器注入

    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.xxx.demo.UserDao"></bean>
    	<!-- 构造器注入 -->
    	<bean id="userServiceV2" class="com.xxx.demo.UserServiceV2">
    		<constructor-arg index="0" ref="userDao"></constructor-arg>
    		<constructor-arg index="1" value="印度三哥"></constructor-arg>
    	</bean>
    </beans>
    

    构造器注入有三种形式:

    index属性为参数顺序,如果只有一个参数index可以不设置。

    name属性根据构造器中属性的名字。

    type属性,是根据构造器中属性的类型来匹配的。如果相同类型属性不唯一,注入的属性按照顺序注入进来。

    UserServiceV2.java类提供构造函数

    /**
     * 实现构造器注入
     * @author Best Liu
     *
     */
    public class UserServiceV2 {
    	private UserDao userDao;
    	private String name;
    	public void userlogin() {
    		String res=userDao.userLogin();
    		System.out.println(res);
    		System.out.println(name);
    	}
    	public UserServiceV2(UserDao userDao,String name) {
    		super();
    		this.userDao = userDao;
    		this.name = name;
    	}
    }
    

    静态工厂注入

    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="userDao01" class="com.xxx.demo.StaticFactory" factory-method="createuserDao"></bean>
    	<bean id="userService01" class="com.xxx.demo.UserService">
    		<property name="userDao" ref="userDao01"></property>
    	</bean>
    </beans>
    

    StaticFactory.java

    public class StaticFactory {
    	public static UserDao createuserDao(){
    		return new UserDao();
    	}
    }
    

    UserService.java

    public class UserService {
    	private UserDao userDao;
    	
    	public void userlogin() {
    		String res=userDao.userLogin();
    		System.out.println(res);
    	}
    
    	public void setUserDao(UserDao userDao) {
    		this.userDao = userDao;
    	}
    }
    

    tips:静态工厂注入就是IoC静态工厂和DI的setter注入,将需要注入的属性对象利用静态工厂创建出来.

    2.4 实例化工厂

    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="instanceFactory" class="com.xxx.demo.InstanceFactory"></bean>
    	<bean id="userDao3" factory-bean="instanceFactory" factory-method="createUserDao"></bean>
    	<bean id="userService02" class="com.xxx.demo.UserService">
    		<property name="userDao" ref="userDao3"></property>
    	</bean>
    </beans>
    

    InstanceFactory.java

    public class InstanceFactory {
    	public UserDao createUserDao(){
    		return new UserDao();
    	}
    }
    

    tips:重点掌握set,构造器注入,工厂方式了解即可,实际开发中基本使用set方式注入bean。

    扩展

    循环依赖的问题的产生

    Bean通过构造器注入,之间彼此相互依赖对方导致bean无法实例化。

    注入的选择:开发项目中set方式注入首选

    使用构造注入可以在构建对象的同时一并完成依赖关系的建立,对象一建立则所有的一切也就准备好了,但如果要建立的对象关系很多,使用构造注入会在构建函数上留下一长串的参数,且不易记忆,这时使用Set注入会是个不错的选择。

    使用Set注入可以有明确的名称,可以了解注入的对象会是什么,像setxxx()这样的名称比记忆Constructor上某个参数的位置代表某个对象更好。

    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="goodsService" class="com.xxx.demo.GoodsService">
    		<!-- <constructor-arg index="0" ref="userService"></constructor-arg> -->
    		<property name="userService" ref="userService"></property>
    	</bean>
    	<bean id="userService" class="com.xxx.demo.UserService">
    		<!-- <constructor-arg index="0" ref="goodsService"></constructor-arg> -->
    		<property name="goodsService" ref="goodsService"></property>
    	</bean>
    </beans>
    

    GoodsService.java

    public class GoodsService {
    	private UserService userService;
    	/*public GoodsService(UserService userService) {
    		super();
    		this.userService = userService;
    	}*/
    	public void setUserService(UserService userService) {
    		this.userService = userService;
    	}
    }
    

    UserService.java

    public class UserService {
    	private GoodsService goodsService;
    /*	public UserService(GoodsService goodsService) {
    		super();
    		this.goodsService = goodsService;
    	}
    */
    	public void setGoodsService(GoodsService goodsService) {
    		this.goodsService = goodsService;
    	}	
    }
    

    在这里插入图片描述

    展开全文
  • 依赖注入容器的 Silex 服务提供者。 它不会取代 Silex 的默认 DI 容器 Pimple,而是添加了 PHP-DI 提供的额外功能。 安装 这个库在上。 要使用 Composer 包含它,请将以下内容添加到您的composer.json : "require...
  • Java开发学习(六)----DI依赖注入之setter及构造器注入解析.doc
  • 一、依赖注入核心组件包: • Microsoft.Extensions.DependencyInjection.Abstractions • Microsoft.Extensions.DependencyInjection 使用接口实现分离模式实现,核心类包括: • IServiceCollection --...

    一、依赖注入核心组件包:

    Microsoft.Extensions.DependencyInjection.Abstractions
    Microsoft.Extensions.DependencyInjection
     
    使用接口实现分离模式实现,核心类包括:
    IServiceCollection  --负责服务的注册;
    ServiceDescriptor  --每一个服务注册的信息;
    • IServiceProvider  --服务具体容器,由 ServiceCollection Build 构建;
    IServiceScope  --表示一个子容器的生命周期;
     
    asp.net core 内置生命周期(ServiceLifetime):
    单例 Singleton,在整个根容器的生命周期内都是单例模式(全局范围);
    • 作用域 Scoped,在容器(或子容器)的生存周期内,若容器释放掉对象也随即释放,同时在容器(或局部作用域)范围内能得到一个单例模式;
    瞬时(暂时)Transient ,每一次从容器获取对象时都可以得到一个全新的对象;
     

    二、服务注册的几种方式:

    在 Startup.cs 文件中,Startup.ConfigureServices 中有如下几种服务注册方式:

    1.常规服务注册:

    #region 注册不同生命周期的服务
    services.AddSingleton<IMySingletonService, MySingletonService>();
    services.AddScoped<IMyScopedService, MyScopedService>();
    services.AddTransient<IMyTransientService, MyTransientService>();
    #endregion

    2.常规服务的“花式”注册:

    services.AddSingleton<IOrderService>(new OrderService());  //直接注入实例
    //同接口(IOrderService)不同实例(OrderServiceEx,OrderService)注册
    services.AddSingleton<IOrderService, OrderServiceEx>(); 
    services.AddSingleton<IOrderService, OrderService>();
    
    //匿名方式注册,可实现具体服务拦截
    services.AddSingleton<IOrderService>(serviceProvider =>
    {
        return new OrderServiceEx(); //serviceProvider 对象可用
    });
    
    services.AddScoped<IOrderService>(serviceProvider =>
    {
        return new OrderServiceEx();
    });

    3.尝试(或试图)注册:

    services.TryAddSingleton<IOrderService, OrderServiceEx>(); //服务被注册就不是再次注册,反之就注册;
    
    //相同类型的服务接口,如果实现不同即可注册,实现相同就不会注册
    services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
    services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService>(new OrderServiceEx()));
    services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService>(p =>
    {
        return new OrderServiceEx();
    }));
    
    //尝试或试图注册的好处:避免重复的服务接口注册或者控制同接口不同实现的服务注册;

    4.移除和替换注册:

    services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>()); //指定原有接口服务的注册,替换(或更改)为现有接口服务实现;
    services.RemoveAll<IOrderService>(); //移除所有的接口服务注册的实例;
    

    5.泛型模板模板注册:

    services.AddSingleton(typeof(IGenericService<>), typeof(GenericService<>));
    
    //使用方式,Controller构造函数注入
    IOrderService _orderService;
    private readonly ILogger<WeatherForecastController> _logger;
    public WeatherForecastController(ILogger<WeatherForecastController> logger, IOrderService orderService, IGenericService<IOrderService> genericService)
    {
       _orderService = orderService; //泛型模板构造函数注入使用
       _logger = logger;
    }

    三、两种依赖注入的实例获取方法:

    1.默认构造函数注入服务使用,通常是接口服务实例的全部使用;(类似如上泛型模板注册)

    2.[FromServices]局部方法注入服务使用,通常指依赖使用某个服务中的一个方法使用;

    [HttpGet]
    public int GetService([FromServices]IMySingletonService singleton1,
                          [FromServices]IMySingletonService singleton2,
                          [FromServices]IMyTransientService transient1,
                          [FromServices]IMyTransientService transient2,
                          [FromServices]IMyScopedService scoped1,
                          [FromServices]IMyScopedService scoped2)
    {
          Console.WriteLine($"singleton1:{singleton1.GetHashCode()}");
          Console.WriteLine($"singleton2:{singleton2.GetHashCode()}");
    
          Console.WriteLine($"transient1:{transient1.GetHashCode()}");
          Console.WriteLine($"transient2:{transient2.GetHashCode()}");
    
          Console.WriteLine($"scoped1:{scoped1.GetHashCode()}");
          Console.WriteLine($"scoped2:{scoped2.GetHashCode()}");
    
          Console.WriteLine($"========请求结束=======");
          return 1;
    }
    
    public int GetServiceList([FromServices]IEnumerable<IOrderService> services)
    {
        foreach (var item in services)
        {
           Console.WriteLine($"获取到服务实例:{item.ToString()}:{item.GetHashCode()}");
        }
        return 1;
    }

    asp.net core 里面的依赖注入,原理介绍见上一篇(ASP.NET Core 2.0系列学习笔记-DI依赖注入):https://blog.csdn.net/ChaITSimpleLove/article/details/79402008

    展开全文
  • Spring 容器使用依赖注入DI)来管理组成一个应用程序的组件。Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。 IOC 容器具有依赖注入功能的容器,它可以创建对象,IOC ...
  • cbsd-di:依赖注入练习

    2021-06-10 08:25:57
    cbsd-di 依赖注入练习
  • 什么是依赖注入?和IOC有什么区别?
  • DI依赖注入原理

    2018-12-26 17:56:23
    DI:dependency injection 依赖注入 在spring框架负责创建Bean对象时,动态将依赖对象注入到Bean组件。 我们在IUserServiceImpl原有基础上添加info属性,提供get set方法 package com.itcast.impl; import ...
  • Spring DI依赖注入讲解

    2018-02-10 11:40:25
    DI:dependency injection 依赖注入 在spring框架负责创建Bean对象时,动态将依赖对象注入到Bean组件。 public class UserServiceImpl implements IUserService { private String info; } &lt;bean id=&...
  • DI依赖注入设计模式

    千次阅读 2020-11-02 10:59:09
    本单将使用依整注入DI)设计模式来将依赖的对象的创建彻底移出类外面去,以获得完全的松耦合的程序设计。 依整注入是一种设计模式。它实现了IOC反转控制原则。它将依赖的类的创建在类外面实现,再通过注入的方式...
  • 这篇文章主要介绍了Spring当中的依赖注入DI),以及他能注入的数据类型,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 什么是依赖注入? Dependency Injection。它是 ...
  • Spring的DI依赖注入(set注入)

    千次阅读 2020-11-04 10:27:11
    为什么叫set注入,是因为实际还是通过反射调用set方法注入,所以要注入的实体类字段要有相应的set方法 现在我们通过一个例子来说明一下 环境 我们有学生类Student,班级类ClassRoom,科目类Subject,书类...
  • 依赖注入DI)的三种方式

    千次阅读 2021-11-10 18:08:49
    个人对依赖注入的理解是:为bean所代表的对象的属性赋值 。对象的属性有多种类型,主要包括基本数据类型、String、引用类型、集合类型、属性类型、空字符串以及空值null。在通过配置文件进行依赖注入时,主要有以下...
  • Spring IOC笔记——DI(依赖注入)的使用详解

    千次阅读 多人点赞 2022-02-10 21:57:57
    Spring IOC,我们又通常将其称为 IOC 容器,IOC 的2个实现方式分别为 依赖注入DI)和 依赖查找(DL)。由于依赖查找(DL)使用的很少,因此 IOC 也被叫做依赖注入。 IOC 底层原理 xml 解析、工厂模式、反射 DI...
  • Spring DI 依赖注入案例(带参数构造方法依赖注入和setter方法依赖注入DI 依赖注入:  简单的说是指对象中的属性的值设置方式不再是调用setter方法进行传值,而是由配置实现经过框架传值。   DI操作可以采用...
  • 什么是DI(依赖注入)

    2020-08-11 19:58:15
    DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率...
  • 也可以集成第三方的依赖注入框架(如:AutoFac做批量注入) DI只负责由其创建的对象实例 DI容器或者子容器释放时,释放由其创建的对象实例 DI负责管理其创建对象的生命周期(创建-->销毁释放) 释放托管资源以及...
  • 深入理解SpringDi依赖注入思想,关注DI与IOC的关系,详细列举了四种依赖注入的使用步骤详解
  • DI依赖注入

    2013-12-09 12:59:33
    DI依赖注入 像则样的bean组件是如何注入的? DI(Dependency injection依赖注入)是IoC实现的重要技术,有如下2种方式: 1)setter方式注入 2)构造方式注入 注入的数据类型有如下几种:简单值(数字、字符等...
  • 依赖注入(DI)常用的两种方式: Spring学习入门时依赖注入(DI)是一个需要了解的概念,其实它就是和IoC从不同角度描述的同一个事物。 下面分别通过实例深入理解两种依赖注入的方式: 1.通过setter方式依赖注入: 1....
  • 依赖注入(DI) 依赖注入(Dependency Injection,DI)。 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 . 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 . 一、构造器注入(默认) 之前使用无参...
  • 方式一、默认就可以注入多个实现类 例如接口IShow,注入ShowA和ShowB两个实现类: services.AddTransient<IShow, ShowA>(); services.AddTransient<IShow, ShowB>(); 获取的时候默认是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 66,853
精华内容 26,741
关键字:

di依赖注入

友情链接: 仿人竞速.zip