spring框架—-依赖注入之setter方法
setter注入
spring的DI(Dependency Injection)依赖注入有三种方式:
1.setter注入
2.构造器注入
3.接口注入
常用的时setter注入和构造器注入。setter注入又根据bean里的属性不同分成:对象注入、值注入(字面量注入)、集合注入、表达式注入、空值注入。
对象注入
1.Hello类
package cn.zgx.ioc;
public class Hello {
public Hello(int i){
}
public Hello(){
System.out.println("hello co");
}
public void sayHello(){
System.out.println("Hello World!!!");
}
**tips:创建实体类时最好提供无参构造,且实现序列化的接口:Serializable
2.清单文件spring.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" >
<!-- 告知spring框架用实例化哪些对象 -->
<!-- id属性时对象在spring容器中的唯一标识,标识符可以带特殊符号 用name也可以 指定对象名,但不能带标识符 class属性时对象的类类型
-->
<bean id="hello" class="cn.zgx.ioc.Hello" >
</bean>
beans>
3.测试类
@Test
public void test1(){
//初始化spring容器
AbstractApplicationContext context =
new ClassPathXmlApplicationContext("conf/spring.xml");
Hello hello=context.getBean("hello",Hello.class);
hello.sayHello();
context.close();
}
输出结果:
hello co
Hello World!!!
值注入
1.ValueInject类
package cn.zgx.value;
public class ValueInject {
private int age;
private String address;
public void setAge(int age) {
this.age = age;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "ValueInject [age=" + age + ", address=" + address + "]";
}
}
2.清单文件spring_setter_value.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">
<!-- 用清单文件告知spring框架对哪些类实例化对象 -->
<!--
property节点告知spring做数据注入 ,对应setter方法
-->
<bean id="valueInject"
class="cn.zgx.value.ValueInject">
<property name="age" value="20"></property>
<property name="address">
<value>北京</value>
</property>
</bean>
</beans>
3.测试类
@Test
public void test2(){
//初始化spring容器
ApplicationContext context =
new ClassPathXmlApplicationContext("conf/spring_setter_value.xml");
ValueInject valueInject=context.getBean("valueInject",ValueInject.class);
System.out.println(valueInject);
}
输出结果:
ValueInject [age=20, address=北京]
集合注入
1.集合类Message
package cn.zgx.collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Message {
private List list;
private Set set;
private Map map;
private Properties props;
public void setList(List list) {
this.list = list;
}
public void setSet(Set set) {
this.set = set;
}
public void setMap(Map map) {
this.map = map;
}
public void setProps(Properties props) {
this.props = props;
}
@Override
public String toString() {
return "Message [list=" + list + ", set=" + set + ", map=" + map + ", props=" + props + "]";
}
}
2.清单文件spring_setter_collection.xml
集合注入分为直接集合注入和间接集合注入,但他们本质上区别不大。集合注入时如果在类中没有对集合做泛型限定,那么集合注入的值可以为任意类型,它也可以用value-ref来从spring容器取对象放进集合中注入。
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 用清单文件告知spring框架对哪些类实例化对象 -->
<bean id="hello"
class="cn.zgx.ioc.Hello" />
<!-- 直接集合注入 -->
<bean id="message"
class="cn.zgx.collection.Message">
<property name="list">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
<ref bean="hello"/>
</list>
</property>
<property name="set">
<set>
<value>北京</value>
<value>上海</value>
<value>广州</value>
<ref bean="hello"/>
</set>
</property>
<property name="map">
<map>
<entry key="bj" value="北京"></entry>
<entry key="sh" value="上海"></entry>
<entry key="gz" value="广州"></entry>
<entry key="h" value-ref="hello" ></entry>
</map>
</property>
<property name="props">
<props>
<prop key="bj">北京</prop>
<prop key="sh">上海</prop>
<prop key="gz">广州</prop>
</props>
</property>
</bean>
<!-- 间接集合 -->
<!-- 集合的对象要交给spring容器来管理 -->
<util:list id="uList">
<value>北京</value>
<value>上海</value>
<value>广州</value>
<ref bean="hello"/>
</util:list>
<util:map id="uMap">
<entry key="bj" value="北京"></entry>
<entry key="sh" value="上海"></entry>
<entry key="gz" value="广州"></entry>
<entry key="h" value-ref="hello" ></entry>
</util:map>
<util:set id="uSet">
<value>北京</value>
<value>上海</value>
<value>广州</value>
<ref bean="hello"/>
</util:set>
<util:properties id="uProps">
<prop key="bj">北京</prop>
<prop key="sh">上海</prop>
<prop key="gz">广州</prop>
</util:properties>
<bean id="message1"
class="cn.zgx.collection.Message">
<property name="list" ref="uList"></property>
<property name="set" ref="uSet"></property>
<property name="map" ref="uMap"></property>
<property name="props" ref="uProps"></property>
</bean>
</beans>
3.测试类
@Test
public void test3(){
ApplicationContext context =
new ClassPathXmlApplicationContext("conf/spring_setter_collection.xml");
Message message=context.getBean("message",Message.class);
System.out.println(message);
}
@Test
public void test4(){
ApplicationContext context =
new ClassPathXmlApplicationContext("conf/spring_setter_collection.xml");
Message message=context.getBean("message1",Message.class);
System.out.println(message);
}
test3输出结果:
Hello constructor()
Message [list=[北京, 上海, 广州, cn.zgx.ioc.Hello@4b1c1ea0], set=[北京, 上海, 广州, cn.zgx.ioc.Hello@4b1c1ea0], map={bj=北京, sh=上海, gz=广州, h=cn.zgx.ioc.Hello@4b1c1ea0}, props={bj=北京, sh=上海, gz=广州}]
test4输出结果:
Hello constructor()
Message [list=[北京, 上海, 广州, cn.zgx.ioc.Hello@4b1c1ea0], set=[北京, 上海, 广州, cn.zgx.ioc.Hello@4b1c1ea0], map={bj=北京, sh=上海, gz=广州, h=cn.zgx.ioc.Hello@4b1c1ea0}, props={bj=北京, sh=上海, gz=广州}]
表达式注入
表达式注入又分为两种:${}和#{}表达式,常用于读取属性文件的值
1.属性文件mysql.properties
jdbc_driverClass=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/tesdb
jdbc_userName=root
jdbc_userPassword=root
jdbc工具类:
package cn.zgx.expression;
import org.springframework.stereotype.Component;
@Component("jdbcutil")
public class JDBCUtil {
private String driverClass;
private String url;
private String username;
private String userpassword;
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setUserpassword(String userpassword) {
this.userpassword = userpassword;
}
@Override
public String toString() {
return "JDBCUtil [driverClass=" + driverClass + ", url=" + url + ", username=" + username + ", userpassword="
+ userpassword + "]";
}
}
2.清单文件
spring_setter_expression1.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 用清单文件告知spring框架对哪些类实例化对象 -->
<!-- 属性注入 用$方式
location属性可以放置多个属性文件,用逗号间隔,建议用类路径classpath取,
仅针对spring框架
把属性文件的数据加载到spring容器中-->
<context:property-placeholder location="classpath:conf/mysql.properties"/>
<bean id="jdbcUtil"
class="cn.zgx.expression.JDBCUtil">
<property name="driverClass" value="${jdbc_driverClass}"></property>
<property name="url" value="${jdbc_url}"></property>
<property name="username" value="${jdbc_userName}"></property>
<property name="userpassword" value="${jdbc_userPassword}"></property>
</bean>
</beans>
spring_setter_expression2.xml
#{}方式
用此方式要给存到spring容器的属性文件一个id值,在根据这个id值取里面的数据
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 用清单文件告知spring框架对哪些类实例化对象 -->
<!-- 属性注入 #{} 多个文件用逗号间隔 ,必须给一个id
把属性文件的数据存储给spring容器,容器中以manyProperty,值是若干属性键值对
-->
<util:properties
id="manyProperty"
location="classpath:conf/mysql.properties"></util:properties>
<bean id="jdbcUtil"
class="cn.zgx.expression.JDBCUtil">
<property name="driverClass" value="#{manyProperty.jdbc_driverClass}"></property>
<property name="url" value="#{manyProperty.jdbc_url}"></property>
<property name="username" value="#{manyProperty.jdbc_userName}"></property>
<property name="userpassword" value="#{manyProperty.jdbc_userPassword}"></property>
</bean>
</beans>
3.测试类
@Test
public void test5(){
ApplicationContext context =
new ClassPathXmlApplicationContext("conf/spring_setter_expression1.xml");
JDBCUtil jdbcUtil=context.getBean("jdbcUtil",JDBCUtil.class);
System.out.println(jdbcUtil);
}
@Test
public void test6(){
ApplicationContext context =
new ClassPathXmlApplicationContext("conf/spring_setter_expression2.xml");
JDBCUtil jdbcUtil=context.getBean("jdbcUtil",JDBCUtil.class);
System.out.println(jdbcUtil);
}
test5和test6都应输出:
JDBCUtil [driverClass=com.mysql.jdbc.Driver, url=jdbc:mysql://localhost:3306/tesdb, username=root, userpassword=root]
空值注入
1.kong类
package cn.zgx.kong;
public class Kong {
private String str1;
private String str2;
public void setStr1(String str1) {
this.str1 = str1;
}
public void setStr2(String str2) {
this.str2 = str2;
}
@Override
public String toString() {
return "Kong [str1='" + str1 + "', str2=" + str2 + "]";
}
}
2.清单文件spring_setter_kong.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 用清单文件告知spring框架对哪些类实例化对象 -->
<bean id="kong"
class="cn.zgx.kong.Kong">
<property name="str1" value=""></property>
<property name="str2">
<null></null>
</property>
</bean>
</beans>
3.测试类:
@Test
public void test7(){
//初始化spring容器
ApplicationContext context =
new ClassPathXmlApplicationContext("conf/spring_setter_kong.xml");
Kong kong=context.getBean("kong",Kong.class);
System.out.println(kong);
}
输出结果:
Kong [str1=’’, str2=null]
总结:
1.setter方法常用的还是值注入和对象注入。对象注入是从spring容器中取出对应对象注入。setter方法要求bean节点的property属性名必须与该节点对应类中有匹配的setter方法,匹配规则是setter方法去掉set并将剩下的字符串首字母小写作为property属性名。比如,bean节点的class属性指向的类有一个setUsername,那么它对应的属性名应该为username。
2.空值注入是很鸡肋的写法。
<property name="str1" value=""></property>//相当于str1=""
<property name="str2">
<null></null>//相当于str2=null
</property>