如果说控制反转(ioc)是我们想要通过spring框架达到的目的,那么依赖注入(di)便是我们强有力的手段!以此来实现高内聚低耦合!
这里有一个A类
有什么方法可以让我们在不使用NEW的情况下创建出来该A类对象呢?
见证奇迹的时刻到了
一.我们创建一个Maven工程,
二.导包spring-webmvc ,Junit
三.
创建一个B类,构建其无参构造器,在B类中创建一个方法b1(),再创建一个s(),后面用得到,-----上代码:
package ioc;
public class B {
public B() {
System.out.println("B()");
}
public void b1() {
System.out.println("B.b1()");
}
public void s() {
System.out.println("B.s()");
}
}
创建一个A类,构建其无参构造器,A类中定义一个未初始化的B对象,然后自动构建get(),Set().,在A类中创建一个方法a1()
既然A类已经定义B对象了,那么可以使用B对象的方法,在a1()中调用b1()-----上代码
package ioc;
public class A {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
System.out.println("setB()");
this.b = b;
}
public A() {
System.out.println("A()");
}
public void a1() {
b.b1();
System.out.println("A.a1()");
}
}
四.分析:
正常情况下,如果我们想调用A对象的a1方法,只需要 A a=new A(); a.a1();
但是这样就会形成高耦合的局面,
这个时候,就是我们spring框架大展身手的时候了
五.创建一个xml的spring配置文件:名称随便起,这里我起名叫做ioc.xml,里面<beans></beans>标签中的这一大串属性就相当于规定的格式,具体干啥的不知道,反正要有就是了
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
">
</beans>
六.创建<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
">
<bean id="b" class="ioc.B" init-method="s">
</bean>
<!-- <property>表示使用set方法注入依赖关系
name 属性是A类中的参数B ref属性是被注入的bean的id
-->
<bean id="a" class="ioc.A">
<property name="B" ref="b"></property>
</bean>
</beans>
bean标签中,id是唯一的,用来在Java代码中通过id调用,class是类的全限定名称,简称"全称".
第一个<bean>声明的是B类 init-mehod属性表示当对象B被创建后立即调用的该类的初始化方法,还有一个销毁属性:destroy-method 功能大同小异
第二个<bean>声明的是A类,并有个子标签<property> ,这个标签代码中给出注释了.
七.写一个Test方法,先上代码:
package test;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import ioc.A;
import ioc.B;
public class testCase {
@Test
public void test1() {
//是ApplicationContext的子类,有close方法.
AbstractApplicationContext aac=new ClassPathXmlApplicationContext("ioc.xml");
System.out.println("spring容器启动成功");
//创建了A类对象
A a=aac.getBean("a",A.class);
//创建了B类对象
B b=aac.getBean("b",B.class);
a.a1();
//最后请记得关闭容器
aac.close();
}
}
各种注释解释都已经写在代码里了,还是放在代码里舒服!
这里我的配置文件叫做ioc.xml.所以启动容器需要用的我的配置文件名字
aac.getBean(),该方法的第一个参数可以通过配置文件中的id值创建相应的对象,第二个参数用到了Java的反射机制,小白的我不懂所以就想象成一个创建"谁"就 "谁".class
最后给出执行结果!
---------------------------------------------------------------------------------------------------------------------------------------
以上为set方式注入依赖,现在写构造器方式注入依赖
A类中不需要B的set()了,但是需要一个A的有参构造器,public A (B b){};
上图:
配置文件中依赖关系也不等用property标签来配置了,更改为:上图
因为可能有多个参数,所以可以写多个constrctor-arg标签,用下标区分注入依赖.
------------------------------------------------------------------------------------------------------------------------------
基本类型的值的注入
前言:基本类型的值的注入很简单在配置文件中稍加改动:
可以注入:基本类型,List ,Map ,Properties, 类型的 当然 List<Map<Integer,Douber>> 这种组合在一起的也是支持的!
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
">
<bean id="v1" class="value.valueBean">
<!-- 基本类型 使用value属性注入值 property表示使用SET方法注入-->
<property name="name" value="胡八一"></property>
<property name="id" value="0001"></property>
<!--List使用子标签<list>-->
<property name="ls">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
<value>深圳</value>
</list>
</property>
<!--Set使用子标签<set>-->
<property name="ss">
<set>
<value>北京</value>
<value>上海</value>
<value>广州</value>
<value>深圳</value>
</set>
</property>
<!-- Map使用<map>子标签,其子标签entry... -->
<property name="mis">
<map>
<entry key="1" value="A"></entry>
<entry key="2" value="B"></entry>
</map>
</property>
<!--properties注入使用<prop>子标签,属性为....-->
<property name="p">
<props>
<prop key="username">1</prop>
<prop key="password">2</prop>
</props>
</property>
<!-- 这是组合起来的,自己琢磨吧,很简单 -->
<property name="lmss">
<list>
<map>
<entry key="name1" value="tom"></entry>
<entry key="age1" value="999"></entry>
</map>
<map>
<entry key="name2" value="los"></entry>
<entry key="age2" value="999"></entry>
</map>
</list>
</property>
</bean>
</beans>
上Java代码:
package value;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class valueBean {
private int id;
private String name;
private List<String> ls;
private Set<String> ss;
private Map<Integer,String> mis;
private Properties p;
private List<Map<String,String>> lmss;
public void setLmss(List<Map<String, String>> lmss) {
this.lmss = lmss;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public valueBean() {
System.out.println("实例化了");
}
@Override
public String toString() {
return "valueBean [id=" + id + ", name=" + name + ", ls=" + ls + ", ss=" + ss + ", mis=" + mis + ", p=" + p
+ ", lmss=" + lmss + "]";
}
public void setLs(List<String> ls) {
this.ls = ls;
}
public void setSs(Set<String> ss) {
this.ss = ss;
}
public void setMis(Map<Integer, String> mis) {
this.mis = mis;
}
public void setP(Properties p) {
this.p = p;
}
}
set方式 注入!
------------------------------------------------------------------------------------------------------
自动装配
自动装配使用<autowir>标签,
底层也是使用构造器或者set方法注入的,有两种autowire方式:
byName 安全的
byType 不太安全的
上配置文件代码:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
">
<!--
如果通过byType自动注入不可以写多个bean class属性是相同的,这样它就不知道用哪个bean了
-->
<bean id="t" class="zidogn_zhuangpei.T" >
</bean>
<bean id="t1" class="zidogn_zhuangpei.T" >
</bean>
<!-- autowire属性表示自动装配 属性有如下三个值
byName 表示让容器根据属性名(id)查找对应的bean,然后调用对应的set方法 来完成注入,如果找不到对应的bean ,则注入null ,不可能找到多个bean
byType 容器依据属性(class)类型查找对应的bean,然后调用set完成注入,可能找到多个bean
-->
<bean id="l" class="zidogn_zhuangpei.L" autowire="byName">
</bean>
<bean id="l" class="zidogn_zhuangpei.L" autowire="byType">
</bean>
</beans>
Java代码:
注入类:
package zidogn_zhuangpei;
public class T {
public T() {
System.out.println("注入类");
}
}
被注入类:
package zidogn_zhuangpei;
public class L {
private T t;
public L() {
System.out.println("被注入类");
}
public void setT(T t) {
System.out.println("setT()");
this.t = t;
}
@Override
public String toString() {
return "l [t=" + t + "]";
}
}
可以看到,我们底层依旧是使用set方法注入