依赖注入
常用:构造方法注入、setter注入
注意:实例注入和静态工厂注入
注意:实例注入和静态工厂注入
构造方法注入
构造方法可以根据参数索引、参数类型、参数名注入(有限制)或者使用
@ConstructorProperties在构造方法上来指定参数名
HelloImpl.java
package com.hello.dao.Impl;
import java.beans.ConstructorProperties;
import com.hello.dao.HelloDao;
public class HelloImpl implements HelloDao{
private int id;
private String password;
//@ConstructorProperties(value = { "id","password" })
public HelloImpl(int id,String password) {
this.id=id;
this.password=password;
}
@Override
public void sayHello() {
System.out.println("id:"+id+"/password:"+password);
}
}
applicationContext.xml
<!--id为组件名 class为组件类 -->
<bean id="byIndex" class="com.hello.dao.Impl.HelloImpl">
<!--index为索引从0开始 -->
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="111"></constructor-arg>
</bean>
<!--除了基本类型以外 其余必须填写全限定类名 -->
<bean id="byType" class="com.hello.dao.Impl.HelloImpl">
<constructor-arg type="int" value="2"></constructor-arg>
<constructor-arg type="java.lang.String" value="222"></constructor-arg>
</bean>
<!--构造函数的参数名 -->
<bean id="byName" class="com.hello.dao.Impl.HelloImpl">
<constructor-arg name="id" value="3"></constructor-arg>
<constructor-arg name="password" value="333"></constructor-arg>
</bean>
HelloTest.java
package com.test;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hello.dao.HelloDao;
public class HelloTest extends TestCase {
public void testHelloWorld(){
//实例化IoC容器
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean 这里是实现接口
HelloDao helloDao1=context.getBean("byIndex",HelloDao.class);
HelloDao helloDao2=context.getBean("byType",HelloDao.class);
HelloDao helloDao3=context.getBean("byName",HelloDao.class);
//执行业务
helloDao1.sayHello();
helloDao2.sayHello();
helloDao3.sayHello();
}
}
setter注入
对Bean类的setter方法进行注入
HelloImpl.java
package com.hello.dao.Impl;
import com.hello.dao.HelloDao;
public class HelloImpl implements HelloDao{
private int id;
private String password;
@Override
public void sayHello() {
System.out.println("id:"+id+"/password:"+password);
}
public void setId(int id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
}
applicationContext.xml
<!--id为组件名 class为组件类 -->
<bean id="bySet" class="com.hello.dao.Impl.HelloImpl">
<!--setId()则name为id -->
<property name="id"><value>4</value></property>
<property name="password" value="444"></property>
</bean>
HelloTest.java
package com.hello.dao.Impl;
import java.beans.ConstructorProperties;
import com.hello.dao.HelloDao;
public class HelloImpl implements HelloDao{
private int id;
private String password;
//@ConstructorProperties(value = { "id","password" })
public HelloImpl(int id,String password) {
this.id=id;
this.password=password;
}
@Override
public void sayHello() {
System.out.println("id:"+id+"/password:"+password);
}
}
applicationContext.xml
<!--id为组件名 class为组件类 -->
<bean id="byIndex" class="com.hello.dao.Impl.HelloImpl">
<!--index为索引从0开始 -->
<constructor-arg index="0" value="1"></constructor-arg>
<constructor-arg index="1" value="111"></constructor-arg>
</bean>
<!--除了基本类型以外 其余必须填写全限定类名 -->
<bean id="byType" class="com.hello.dao.Impl.HelloImpl">
<constructor-arg type="int" value="2"></constructor-arg>
<constructor-arg type="java.lang.String" value="222"></constructor-arg>
</bean>
<!--构造函数的参数名 -->
<bean id="byName" class="com.hello.dao.Impl.HelloImpl">
<constructor-arg name="id" value="3"></constructor-arg>
<constructor-arg name="password" value="333"></constructor-arg>
</bean>
HelloTest.java
package com.test;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hello.dao.HelloDao;
public class HelloTest extends TestCase {
public void testHelloWorld(){
//实例化IoC容器
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean 这里是实现接口
HelloDao helloDao1=context.getBean("byIndex",HelloDao.class);
HelloDao helloDao2=context.getBean("byType",HelloDao.class);
HelloDao helloDao3=context.getBean("byName",HelloDao.class);
//执行业务
helloDao1.sayHello();
helloDao2.sayHello();
helloDao3.sayHello();
}
}
setter注入
package com.hello.dao.Impl;
import com.hello.dao.HelloDao;
public class HelloImpl implements HelloDao{
private int id;
private String password;
@Override
public void sayHello() {
System.out.println("id:"+id+"/password:"+password);
}
public void setId(int id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
}
applicationContext.xml
<!--id为组件名 class为组件类 -->
<bean id="bySet" class="com.hello.dao.Impl.HelloImpl">
<!--setId()则name为id -->
<property name="id"><value>4</value></property>
<property name="password" value="444"></property>
</bean>
package com.test;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hello.dao.HelloDao;
public class HelloTest extends TestCase {
public void testHelloWorld(){
//实例化IoC容器
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean 这里是实现接口
HelloDao helloDao1=context.getBean("bySet",HelloDao.class);
//执行业务
helloDao1.sayHello();
}
}
常量注入
<property name="id"><value>4</value></property>
<property name="password" value="444"></property>
两种写法均可以,第二种较为简洁
value中的是字符串,IoC容器会自动进行类型转换,如果类型转换出错则抛出异常
注意:对于String转boolean,Spring有容错机制"true/false"可以写成"yes/no"、“on/off”、“1/0”
集合数组字典properties注入
- 集合
ListBean.java
package com.list;
import java.util.List;
public class ListBean {
private List<String> list;
public int listLength(){
return this.list.size();
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
application.xml
<bean id="listBean" class="com.list.ListBean">
<!--name依然为set注入 -->
<property name="list">
<!-- 1 value-type指定条目的数据类型 -->
<!-- 2 Spring会根据泛型指定条目的数据类型 -->
<!-- 3 若没有value-type也没有泛型,则默认为String类型 -->
<list value-type="java.lang.String">
<value>!1!</value>
<value>!2!</value>
<value>!3!</value>
</list>
</property>
</bean>
Test.java
package com.test;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hello.dao.HelloDao;
import com.list.ListBean;
public class Test extends TestCase{
public void testBean(){
//实例化IoC容器
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean 这里是实现接口
ListBean listBean=context.getBean("listBean",ListBean.class);
//执行业务
System.out.println(listBean.listLength());
}
}
set类型注入是xml中需要用<set>替换<list>,用法和list一样
而collection则<set>和<list>都能使用
- 数组
- map
properties
Bean的引用
可以通过构造方法注入和setter注入引用其他Bean
<constructor-arg index="0" value="1">和<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;"><property name="password" value="444">用bean属性替换value属性,bean属性填写别的bean的id或者别名</span>
用<ref bean="">替换<value>,<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">bean属性填写别的bean的id或者别名</span>
其他方式的引用
<ref local="">和<ref parent="">
- <ref local="">引用的是当前配置文件中用id属性(不会找name和别名)指定的bean即<bean id="">,找不到则抛出异常
- <ref parent="">查找父容器不会查找本地容器
HelloImpl.java
package com.hello.dao.Impl;
import com.hello.dao.HelloDao;
public class HelloImpl implements HelloDao{
private HelloParent helloParent;
private HelloLocal helloLocal;
@Override
public void sayHello() {
System.out.println("parent=name:"+helloParent.getName()+";msg:"+helloParent.getMsg());
System.out.println("local=name:"+helloLocal.getName()+";msg:"+helloLocal.getMsg());
}
public HelloParent getHelloParent() {
return helloParent;
}
public void setHelloParent(HelloParent helloParent) {
this.helloParent = helloParent;
}
public HelloLocal getHelloLocal() {
return helloLocal;
}
public void setHelloLocal(HelloLocal helloLocal) {
this.helloLocal = helloLocal;
}
}
applicationContextParent.xml
<!--父容器 bean -->
<bean id="beanParent" class="com.hello.dao.Impl.HelloParent">
<!--name依然为set注入 -->
<property name="name" value="parent"></property>
<property name="msg" value="hello this is parent"/>
</bean>
applicationContext.xml
<!--id为组件名 class为组件类 -->
<bean id="byRefPandL" class="com.hello.dao.Impl.HelloImpl">
<!--name依然为set注入 -->
<property name="helloParent"><ref parent="beanParent"/> </property>
<property name="helloLocal"><ref local="beanLocal"/></property>
</bean>
<!--本地容器 bean -->
<bean id="beanParent" class="com.hello.dao.Impl.HelloParent">
<!--name依然为set注入 -->
<property name="name" value="parent"/>
<property name="msg" value="hello this is Local"/>
</bean>
<bean id="beanLocal" class="com.hello.dao.Impl.HelloLocal">
<!-- name依然为set注入 -->
<property name="name" value="local"/>
<property name="msg" value="hello this is Local"/>
</bean>
ParentLocalTest.java
package com.test;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.hello.dao.HelloDao;
public class ParentLocalTest extends TestCase {
public void testHelloWorld(){
//实例化IoC容器
ApplicationContext parentContext =new ClassPathXmlApplicationContext("applicationContextParent.xml");
ApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}, parentContext);
//获取bean 这里是实现接口
HelloDao helloDao1=context.getBean("byRefPandL",HelloDao.class);
//执行业务
helloDao1.sayHello();
}
}