Spring-(3)Spring DI
来源:互联网 发布:ipad淘宝没有免费试用 编辑:程序博客网 时间:2024/05/19 13:28
Spring-(3)Spring DI
DI:Dependency Injection,即“依赖注入”,依赖注入可以有高效的解耦合的能力。可以说,依赖注入仅仅是控制反转的一个具体的例子,当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能的独立于其他的 Java 类来增加这些类可重用的可能性,当进行单元测试时,可以使它们独立于其他类进行测试。依赖注入有助于将这些类粘合在一起,并且在同一时间让它们保持独立。我们将这两个部分拆开来理解,依赖的关系就像是类里面套着另一个类,例如车店是一个类,车店类里面有一个属性是车主类,那么车店类就依赖了车主类,这就是依赖关系,那注入的意思是车主类通过IOC容器注入到车店!
每个基于应用程序的 java 都有几个对象,这些对象一起工作来呈现出终端用户所看到的工作的应用程序。当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能独立于其他 Java 类来增加这些类重用的可能性,并且在做单元测试时,测试独立于其他类的独立性。依赖注入(DI)有助于把这些类粘合在一起,同时保持他们独立。
Spring 有两种依赖注入类型
- Constructor-based dependency injection:当容器调用带有多个参数的构造函数类时,实现基于构造函数的 DI,每个代表在其他类中的一个依赖关系;
Setter-based dependency injection:基于 setter 方法的 DI 是通过在调用无参数的构造函数或无参数的静态工厂方法实例化 bean 之后容器调用 beans 的 setter 方法来实现的.
你可以混合这两种方法,基于构造函数和基于 setter 方法的 DI,然而使用有强制性依存关系的构造函数和有可选依赖关系的 setter是一个好的做法。
现在我们从一个例子里面了解一下依赖注入的实现:
我们创建两个pojo类,分别为Company类和Person类
-Company类
public class Company { private Person person; public Company() {} public Company(Person person) { System.out.println("公司有很多人!"); this.person = person; } public void setPerson(Person person) { System.out.println("公司有很多人!"); this.person = person; }}
-Person类
public class Person { private String say; public Person() {} public Person(String say) { System.out.println(say); this.say = say; } public void setSay(String say) { System.out.println(say); this.say = say; }}
那么我们开始分别对基于构造函数和基于setter进行依赖注入,在Beans.xml文件中添加下面相应的代码块,这里我们先使用xml进行配置(以后讲到注解再用注解进行配置)
基于构造函数的依赖注入
<bean id="constructorCompany" class="com.tbspringDI.constructor.Company" lazy-init="true"> <constructor-arg ref="constructorPerson"></constructor-arg> </bean> <bean id="constructorPerson" class="com.tbspringDI.constructor.Person" lazy-init="true"> <constructor-arg type="java.lang.String" value="我是人,我说了一句人话!"></constructor-arg> </bean>
基于setter的依赖注入
<bean id="setterCompany" class="com.tbspringDI.setter.Company" lazy-init="true"> <property name="person" ref="setterPerson"></property> </bean> <bean id="setterPerson" class="com.tbspringDI.setter.Person" lazy-init="true"> <property name="say" value="我是人,我说了一句人话!"></property> </bean>
需要注意的是:基于构造函数的依赖注入需要pojo存在相应的构造方法,而基于setter的依赖注入则需要pojo存在相应的setXxx()方法。
下面用main方法进行一下测试:
public class MainAPP { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); //基于构造函数注入就将下面getBean的()里面改为constructorCompany Company company = (Company) context.getBean("setterCompany"); }}
控制台输出下面两句话我们就成功啦!
但为什么我们拿得是Company对象会输出两句话呢?
这是因为当我们从IOC容器中取Company是,IOC帮我们先把Person初始化了一遍,所以我们会看到控制台会先输出一句“我是人,我说了一句话!”
除了以上两种用法外,DI还有另外的两种两种用法
1.innerBean(内部Bean):在Beans.xml中替换相应Bean即可
<bean id="outerBeansCompany" class="com.tbspringDI.innerBeans.Company" lazy-init="true"> <property name="person"> <bean id="innerBeansPerson" class="com.tbspringDI.innerBeans.Person"> <property name="say" value="我是人,我说了一句话!"></property> </bean> </property></bean>
2.集合注入:看个用例,我们创建一个JavaCollection类并在Beans.xml中进行配置
JavaCollection类
public class JavaCollection { private List addressList; private Set addressSet; private Map addressMap; private Properties addressProp; public List getAddressList() { System.out.println("List Elements :" + addressList); return addressList; } public void setAddressList(List addressList) { this.addressList = addressList; } public Set getAddressSet() { System.out.println("Set Elements :" + addressSet); return addressSet; } public void setAddressSet(Set addressSet) { this.addressSet = addressSet; } public Map getAddressMap() { System.out.println("Map Elements :" + addressMap); return addressMap; } public void setAddressMap(Map addressMap) { this.addressMap = addressMap; } public Properties getAddressProp() { System.out.println("Property Elements :" + addressProp); return addressProp; } public void setAddressProp(Properties addressProp) { this.addressProp = addressProp; }}
Beans.xml中添加下列代码块
<!-- 注入集合 --><bean id="javaCollection" class="com.tbspringDI.setCollection.JavaCollection"> <!-- 注入一列值,允许重复 --> <property name="addressList"> <list> <value>INDIA</value> <value>Pakistan</value> <value>USA</value> <value>USA</value> </list> </property> <!-- 注入一列值,不允许重复 --> <property name="addressSet"> <set> <value>INDIA</value> <value>Pakistan</value> <value>USA</value> <value>USA</value> </set> </property> <!-- 键值对,可以是任意类型 --> <property name="addressMap"> <map> <entry key="1" value="INDIA"/> <entry key="2" value="Pakistan"/> <entry key="3" value="USA"/> <entry key="4" value="USA"/> </map> </property> <!-- 键值对,String类型 --> <property name="addressProp"> <props> <prop key="one">INDIA</prop> <prop key="two">Pakistan</prop> <prop key="three">USA</prop> <prop key="four">USA</prop> </props> </property> </bean>
然后我们写个测试类(MainAPP)进行一下测试:
public class MainAPP { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); JavaCollection jc=(JavaCollection)context.getBean("javaCollection"); jc.getAddressList(); jc.getAddressSet(); jc.getAddressMap(); jc.getAddressProp(); }}
输出结果如下:
我们可以看到以下区别:
- 1.list的列值是可以重复的
- 2.set的列值是不能重复的
- 3.map输出的是Object类型的键值对
- 4.Properties输出的是String类型的键值对
以上就是Spring依赖注入的用法,仅供学习参考。
- Spring-(3)Spring DI
- spring di
- Spring DI
- Spring DI
- Spring()---DI
- Spring DI
- spring di
- spring DI
- spring DI
- Spring 1 IoC 3 DI
- 3、Spring IOC&DI使用
- spring依赖注入(DI)
- Spring 依赖注入(DI)
- spring初学一(DI)
- spring-DI(依赖注入)
- Spring(四):IOC,DI
- Spring依赖注入(DI)
- Spring依赖注入(DI)
- org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.Reflecti
- 读《练习的心态》
- 国内maven 仓库(阿里云提供)
- UVa10935-Throwing cards away I-卡片游戏-队列的运用
- spring配置quartz:定时去执行一个方法
- Spring-(3)Spring DI
- MySql中的先聚合再筛选与先筛选再聚合
- 各大网站CSS初始化代码集合
- Eclipse-Maven项目找不到类not class found
- mysql简介&基本语句
- JAVA printWriter中write()和println()区别(特别注意)
- 约瑟夫环
- Spring boot 与原有配置比较
- Python tips: 什么是*args和**kwargs?