1.1注入外部Bean
在之前使用的案例就是注入外部Bean的方式。
<!-- class属性声明要管理哪个类中的对象
property标签的name是提示set方法名
ref标签指明注入的bean的id-->
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<property name="userDao" ref="userDaoBean"/>
</bean>
</beans>
外部Bean的特点:bean定义到外面,在property标签中使用ref属性进行注入。通常这种方式是常用。
1.2注入内部Bean
内部Bean的特点:在bean标签中嵌套bean标签,以取代property种的ref标签.少用.
<!-- ref标签指明注入的bean的id
没有了ref标签,用另一个bean标签的class标签指明注入的bean所在的类(进而找到该bean)-->
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<property name="userDao">
<bean class="com.sunsplanter.spring6.dao.UserDao"/>
</property>
</bean>
2.1注入简单类型
我们之前在进行注入的时候,是将获取到的对象注入到另一个对象中。
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
对于简单类型,也就是
● 基本数据类型
● 基本数据类型对应的包装类
● String或其他的CharSequence子类
● Number子类
● Date子类
● Enum子类
● URI
● URL
● Temporal子类
● Locale
● Class
● 另外还包括以上简单值类型对应的数组类型
该如何注入?
和对象注入的基本方法完全一致.
即完成spring配置文件,src中定义要注入的类,对象,属性,test中进行单元测试.
项目结构
其中,JDBC测试简单数据类型string;SimpleValue_Array测试数组,且数组中数据是简单数据类型;NonSimpleValue_Array测试数组,且数组中数据是非简单数据类型,这三组测试公用一个set-di.xml的spring配置,共用一个SpringDITest测试类.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--测试注入JDBC数据源
property标签的name属性是提示set方法名。
property标签的value属性是要注入的bean对象的直接值(注入简单类型时可用)。
property标签的ref属性是要注入的bean对象的id。
property标签的ref子标签是声明要注入数组的非简单数据的bean的id。-->
<bean id="myDataSource" class="com.sunsplanter.JDBC.MyDataSource">
<property name="driver" value=""/>
<property name="url" value="jdbc:mysql.cj.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="Mysql998168"/>
</bean>
<!-- 测试注入数组,且数组个数据是简单类型,因此在array中使用value子标签注入
在property下添加一个array子标签-->
<bean id="person" class="com.sunsplanter.SimpleValueTest.SimpleValue_Array">
<property name="favariteFoods">
<array>
<value>鸡排</value>
<value>汉堡</value>
<value>鹅肝</value>
</array>
</property>
</bean>
<!-- 测试注入数组,且数组中数据是非简单类型,因此在array中使用value子标签注入-->
<bean id="goods1" class="com.sunsplanter.NonSimpleValue_Array.Goods">
<property name="name" value="西瓜"/>
</bean>
<bean id="goods2" class="com.sunsplanter.NonSimpleValue_Array.Goods">
<property name="name" value="苹果"/>
</bean>
<bean id="order" class="com.sunsplanter.NonSimpleValue_Array.Order">
<property name="goods">
<array>
<!--Order是一个数组.且数组中元素是非简单类型,因此在array中采用ref标签注入-->
<ref bean="goods1"/>
<ref bean="goods2"/>
</array>
</property>
</bean>
<!-- list集合有序可重复
set集合无序不可重复-->
<!--
提前在SpringDITest中声明一个set,并指明是String类型
private Set<String> phones;
<bean id="peopleBean" class="com.powernode.spring6.beans.People">
<property name="phones">
<set>
非简单类型可以使用ref,简单类型使用value
<value>110</value>
<value>110</value>
<value>120</value>
</set>
</property>
</bean>
提前在SpringDITest中声明一个list,并指明是String类型
private List<String> names;
<bean id="peopleBean" class="com.powernode.spring6.beans.People">
<property name="names">
<list>
<ref bean="people1"/>
<ref bean="people2"/>
</list>
</property>
</bean>
-->
<!-- 注入键值对的集合map-->
<!--
提前在SpringDITest中声明一个Map键值对,并指明是键是整数类型,值是String类型
private Map<Integer, String> addrs;
<bean id="peopleBean" class="com.powernode.spring6.beans.People">
<property name="addrs">
<map>
如果key是非简单类型,使用 key-ref 属性
如果value是非简单类型,使用 value-ref 属性
<entry key="1" value="北京大兴区"/>
<entry key="2" value="上海浦东区"/>
<entry key="3" value="深圳宝安区"/>
</map>
</property>
</bean>
-->
<!-- cndata是xml提供的语法,有了这个xml就不解析-->
<!-- p命名空间注入本质还是set注入,只不过其让Spring配置更简单-->
</beans>
package com.sunsplanter.test;
import com.sunsplanter.JDBC.MyDataSource;
import com.sunsplanter.NonSimpleValue_Array.Order;
import com.sunsplanter.SimpleValueTest.SimpleValue_Array;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDITest {
@Test
//测试注入JDBC数据源,getBean的name参数即set-di.xml中的bean的id
public void testMyDataSource(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");
MyDataSource myDatataSource = applicationContext.getBean("myDataSource", MyDataSource.class);
System.out.println(myDatataSource);
}
@Test
//测试注入数组,且数组元素为简单类型
public void testArraySimple(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");
SimpleValue_Array simpleValueArray = applicationContext.getBean("person", SimpleValue_Array.class);
System.out.println(simpleValueArray);
}
@Test
//测试注入数组,且数组元素为非简单类型
public void testArray(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");
Order order = applicationContext.getBean("order", Order.class);
System.out.println(order);
}
}
package com.sunsplanter.JDBC;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
//数据源:所有提供connection对象的都是数据源,必须实现DataSource
public class MyDataSource implements DataSource{
//获取数据库连接对象需要4个信息
//这四个数据都是简单数据,用Spring容器管理他们
private String driver;
private String url;
private String username;
private String password;
public void setDriver(String driver) {
this.driver = driver;
}
public void setUrl(String url) {
this.url = url;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "MyDataSource{" +
"driver='" + driver + '\'' +
", url='" + url + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
@Override
public Connection getConnection() throws SQLException {
return null;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}
package com.sunsplanter.NonSimpleValue_Array;
//本次测试用set方法注入数组,且数组元素是非简单类型
//具体来说,定义两个类,分别是Goods和Order,其中,每个Order可能包含多个Good
public class Goods {
private String name;
public Goods() {
}
public Goods(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
'}';
}
}
package com.sunsplanter.NonSimpleValue_Array;
import java.util.Arrays;
public class Order {
// 一个订单中有多个商品
//声明一个数组,将传来的good全部放进数组
private Goods[] goods;
public Order() {
}
public Order(Goods[] goods) {
this.goods = goods;
}
public void setGoods(Goods[] goods) {
this.goods = goods;
}
@Override
public String toString() {
return "Order{" +
"goods=" + Arrays.toString(goods) +
'}';
}
}