1.19beans标签的profile属性
profile用于配置spring的多环境配置。
我们可以通过profile配置多个不同环境下的配置属性。
案例:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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">
<beans profile="test">
<!-- 测试环境下的配置 -->
</beans>
<beans profile="prod">
<!-- 生产环境下的配置 -->
</beans>
</beans>
spring 为我们提供了大量的激活 profile 的方法,可以通过代码来激活,也可以通过系统环境变量、JVM参数、servlet上下文参数来定义 spring.profiles.active 参数激活 profile。
ENV方式:ConfigurableEnvironment.setActiveProfiles("test")
JVM参数方式:set JAVA_OPTS="-Dspring.profiles.active=test"
web.xml方式:
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>production</param-value>
</init-param>
标注方式(junit单元测试非常实用):
@ActiveProfiles({"unittest","productprofile"})
看案例:
我们配置如下,不同的环境下在service中注入不同的dao:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byType" 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">
<!-- 注册accountDAO_mysql -->
<bean id="accountDAO_mysql" autowire-candidate="false" class="com.dk.demo1.dao.impl.AccountDAO_mysql"/>
<!-- 注册accountDAO_oracle -->
<bean id="accountDAO_oracle" class="com.dk.demo1.dao.impl.AccountDAO_oracle"/>
<beans profile="mysql">
<!-- 注册accountService 注入accountDAO_mysql -->
<bean id="accountService" name="a_service"
class="com.dk.demo1.service.AccountService">
<property name="accountDAO" ref="accountDAO_mysql"/>
</bean>
</beans>
<beans profile="oracle">
<!-- 注册accountService 注入accountDAO_mysql -->
<bean id="accountService" name="a_service"
class="com.dk.demo1.service.AccountService">
<property name="accountDAO" ref="accountDAO_oracle"/>
</bean>
</beans>
</beans>
测试:
@Test
public void testSpringProfile(){
//创建spring容器
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
//激活profile
ConfigurableEnvironment environment = ac.getEnvironment();
environment.setActiveProfiles("oracle");
//重启容器
ac.refresh();
AccountService accountService = ac.getBean(AccountService.class);
accountService.save("戴着假发的程序员");
}
1.20 property标签
property是用来给bean的属性配置要注入的值的。这些值可以是bean或者简单值(基本类型和Stirng)。
案例:
/**
* @author 戴着假发的程序员
* @description
*/
public class AccountService {
private IAccountDAO accountDAO;
private String appName;
public void setAppName(String appName) {
this.appName = appName;
}
public void setAccountDAO(IAccountDAO accountDAO) {
this.accountDAO = accountDAO;
}
public int save(String name){
System.out.println("AppName:"+appName);
System.out.println("AccountService-save->保存用户:"+name);
return accountDAO.save(name);
}
}
AccountService中需要注入属性IAccountDAO和appName,我们可以按照下面的方式注入:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byType" 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">
<!-- 注册accountDAO_oracle -->
<bean id="accountDAO_oracle" class="com.dk.demo1.dao.impl.AccountDAO_oracle"/>
<!-- 注册accountService 注入accountDAO_mysql -->
<bean id="accountService" name="a_service"
class="com.dk.demo1.service.AccountService">
<property name="accountDAO" ref="accountDAO_oracle"/>
<!-- 注入简单属性 -->
<property name="appName" value="spring应用手册"/>
<!-- <property name="appName">-->
<!-- <value>spring应用手册</value>-->
<!-- </property>-->
</bean>
</beans>
这样的配置可以让我们从spring容器中获取的accountService对象已经装配好了上面的两个属性。
测试:
@Test
public void testSpringProperty(){
//创建spring容器
ClassPathXmlApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService accountService = ac.getBean(AccountService.class);
accountService.save("戴着假发的程序员");
}
控制台:
1.21 constructor-arg标签
constructor-arg标签和property一样可以通知spring帮我们注入属性。
只不过constructor-arg的配置,spring会通过构造方法注入,这时就需要我们的类中有对应的构造方法。
案例如下:
/**
* @author 戴着假发的程序员
* @description
*/
public class AccountService {
private IAccountDAO accountDAO;//bean的引用类型
private String appName;//简单类型(String和基本数据类型)
public AccountService(IAccountDAO accountDAO, String appName) {
this.accountDAO = accountDAO;
this.appName = appName;
}
public int save(String name){
System.out.println("AppName:"+appName);
System.out.println("AccountService-save->保存用户:"+name);
return accountDAO.save(name);
}
}
这时我们会发现,我们的类不再需要提供无参数的构造方法了。
配置方式如下:
我们可以根据构造方法形参的名字注入:
<!-- 注册accountDAO_oracle -->
<bean id="accountDAO_oracle" class="com.dk.demo1.dao.impl.AccountDAO_oracle"/>
<!-- 注册accountService 注入accountDAO_mysql -->
<bean id="accountService" name="a_service"
class="com.dk.demo1.service.AccountService">
<!-- 使用构造方法注入属性 -->
<constructor-arg name="accountDAO" ref="accountDAO_oracle"/>
<constructor-arg name="appName" value="spring应用手册"/>
</bean>
我们也可以根据参数的索引注入属性:
<!-- 注册accountDAO_oracle -->
<bean id="accountDAO_oracle" class="com.dk.demo1.dao.impl.AccountDAO_oracle"/>
<!-- 注册accountService 注入accountDAO_mysql -->
<bean id="accountService" name="a_service"
class="com.dk.demo1.service.AccountService">
<!-- 使用构造方法注入属性 -->
<constructor-arg index="0" ref="accountDAO_oracle"/>
<constructor-arg index="1" value="spring应用手册"/>
</bean>
当然 constructor-arg还有一个属性type用来指定参数的类型:
<!-- 注册accountDAO_oracle -->
<bean id="accountDAO_oracle" class="com.dk.demo1.dao.impl.AccountDAO_oracle"/>
<!-- 注册accountService 注入accountDAO_mysql -->
<bean id="accountService" name="a_service"
class="com.dk.demo1.service.AccountService">
<!-- 使用构造方法注入属性 -->
<constructor-arg type="com.dk.demo1.dao.IAccountDAO"
index="0" ref="accountDAO_oracle"/>
<constructor-arg index="1" value="spring应用手册"/>
</bean>
通常情况下,spring都会自动识别类型,但是如果一个bean本身拥有多个类型,这时如果我们需要指定特定的类型,就需要使用type指定类型。
1.22 lookup-method标签
lookup-method是spring实现的一种特殊的通过方法注入的方式。
我们看下面的案例:
我们有两个IAccountDAO接口的实现类:
接口:
/**
* @author 戴着假发的程序员
*
* @description
*/
public interface IAccountDAO {
public int save(String name);
}
两个实现类:
/**
* @author 戴着假发的程序员
* @description
*/
public class AccountDAO_mysql implements IAccountDAO {
@Override
public int save(String name){
System.out.println("AccountDAO_mysql-save->保存账户:"+name);
return 1;
}
}
/**
* @author 戴着假发的程序员
* @description
*/
public class AccountDAO_oracle implements IAccountDAO {
@Override
public int save(String name){
System.out.println("AccountDAO_oracle-save->保存账户:"+name);
return 1;
}
}
我们有一个抽象的service类,如下:
/**
* @author 戴着假发的程序员
*
* @description
*/
public abstract class AbstractAccountService {
//非抽象的保存方法
public int save(String name){
System.out.println("AbstractAccountService-save:"+name);
//调用抽象方法获取IAccountDAO对象
return getAccount().save(name);
};
//抽象方法获取IAccountDAO
public abstract IAccountDAO getAccount();
}
这里注意我们的service是一个抽象类,并没有属性IAccountDAO。 我们是通过一个抽象方法getAccount()获取IAccountDAO对象的。(看到这里肯定蒙圈,继续看下面的) 配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byType" 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">
<!-- 注册accountDAO_oracle -->
<bean id="accountDAO_oracle" class="com.dk.demo1.dao.impl.AccountDAO_oracle"/>
<!-- 注册accountDAO_mysql -->
<bean id="accountDAO_mysql" class="com.dk.demo1.dao.impl.AccountDAO_mysql"/>
<!--service配置 分别配置两个 -->
<bean id="accountService_mysql"
class="com.dk.demo1.service.AbstractAccountService">
<!-- 通过lookup-method 通知springgetAccount方法的返回值是 accountDAO_mysql-->
<lookup-method name="getAccount" bean="accountDAO_mysql"/>
</bean>
<bean id="accountService_oracle"
class="com.dk.demo1.service.AbstractAccountService">
<!-- 通过lookup-method 通知springgetAccount方法的返回值是 accountDAO_oracle-->
<lookup-method name="getAccount" bean="accountDAO_oracle"/>
</bean>
</beans>
测试:
@Test
public void testLookup(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext-demo4.xml");
AbstractAccountService bean1 = (AbstractAccountService) ac.getBean("accountService_mysql");
bean1.save("戴着假发的程序员");
AbstractAccountService bean2 = (AbstractAccountService) ac.getBean("accountService_oracle");
bean2.save("daizhejiafadechengxuyuan");
System.out.println(bean1);
System.out.println(bean1);
}
控制台
通过观察我们发现几个问题:
1、AbstractAccountService是一个抽象类,理论上spring无法创建对象。
2、getAccount是个抽象方法,理论上也无法调用。
我们仔细观察控制台输出的bean1和bean2对象,我们会发现这两个对象是通过CGLib产生的代理对象
com.dk.demo1.service.AbstractAccountServiced688190a@799d4f69 com.dk.demo1.service.AbstractAccountServiced688190a@799d4f69
所以Lookup-method的主要作用是:
1、通知spring当前类需要产生代理对象。
2、通知spring当前lookup-method标注的方法的返回值应该是bean属性指定的bean对象。
这样我们就会发现,我们可以通过一个抽象方法为一个抽象类中注入我们希望的bean对象。
1.23 replaced-method标签
replaced-method可以让我们通过配置完成对原有的bean中的方法实现进行重新替换。
看案例:
我们有一个service类,其中有一个save方法的实现
/**
* @author 戴着假发的程序员
*
* @description
*/
public class AccountService {
public void save(String name){
System.out.println("AccountService-save:"+name);
}
}
我们制定一个替换实现类,这个类必须试下你接口: org.springframework.beans.factory.support.MethodReplacer
/**
* @author 戴着假发的程序员
*
* @description
*/
public class ReplacementSaveAccount implements MethodReplacer {
/**
* @param o 产生的代理对象
* @param method 替换的方法对象
* @param objects 提花的方法传入的参数
* @return
* @throws Throwable
*/
@Override
public Object reimplement(Object o, Method method, Object[] objects) throws Throwable {
Object result = null;
System.out.println("当前对象o:"+o);
System.out.println("原来的方法method:"+method);
for (Object arg : objects){
System.out.println("参数--:"+arg);
}
System.out.println("保存账户替换后的方法");
return result;
}
}
配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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">
<!-- 替换Bean ReplacementSaveAccount -->
<bean id="replacementSaveAccount" class="com.boxuewa.dk.demo2.service.ReplacementSaveAccount"/>
<!-- accountService -->
<bean id="accountService" class="com.boxuewa.dk.demo2.service.AccountService">
<!-- 配置替换方法 -->
<replaced-method name="save" replacer="replacementSaveAccount">
<arg-type>String</arg-type>
</replaced-method>
</bean>
</beans>
测试:
@Test
public void testReplaceMethod(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext-demo5.xml");
AccountService bean = ac.getBean(AccountService.class);
bean.save("戴着假发的程序员");
}
结果:
当前对象o:com.boxuewa.dk.demo2.service.AccountService$$EnhancerBySpringCGLIB$$f5322a5a@17776a8
原来的方法method:public void com.boxuewa.dk.demo2.service.AccountService.save(java.lang.String)
参数--:戴着假发的程序员
保存账户替换后的方法
我们会发现spring会为我们生成一个AccountService的代理对象,并且将其save方法的实现修改为我们制定的ReplacementSaveAccount中的reimplement实现。
注意:下面配置中:
<!-- 配置替换方法 -->
<replaced-method name="save" replacer="replacementSaveAccount">
<arg-type>String</arg-type>
</replaced-method>
String可以配置任意多个。 这种情况往往用于AccountService有多个save方法的重载的情况。
1.24 value注入简单数据
我们在使用property和constructor-arg为bean注入属性时,如果属性是简单类型,我们可以通过value直接注入。
这里简单类型主要是指java的基本类型和String类型。
案例:
我们有一个Service类:
/**
* @author 戴着假发的程序员
*
* @description
*/
public class AccountService {
private String appName;
private int count;
public void setAppName(String appName) {
this.appName = appName;
}
public void setCount(int count) {
this.count = count;
}
//无参数构造
public AccountService(){}
//有参数构造
public AccountService(String appName,int count){
this.appName = appName;
this.count = count;
}
@Override
public String toString(){
return "appName:"+appName+";\r\ncount:"+count;
}
}
AccountService有两个简单类型的属性,我们可以通过下面的方式注入属性:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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">
<!-- accountService 方式1 -->
<bean id="accountService1" class="com.dk.demo1.service.AccountService">
<property name="appName" value="假发"/>
<property name="count" value="100"/>
</bean>
<!-- accountService 方式2 -->
<bean id="accountService2" class="com.dk.demo1.service.AccountService">
<property name="appName"><value>程序员</value></property>
<property name="count"><value>1000000</value></property>
</bean>
<!-- accountService 方式3 -->
<bean id="accountService3" class="com.dk.demo1.service.AccountService">
<constructor-arg name="appName" value="戴假发"/>
<constructor-arg name="count" value="999"/>
</bean>
<!-- accountService 方式4 -->
<bean id="accountService4" class="com.dk.demo1.service.AccountService">
<constructor-arg name="appName">
<value>有假发</value>
</constructor-arg>
<constructor-arg name="count">
<value>99</value>
</constructor-arg>
</bean>
</beans>
测试:
@Test
public void testValue(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService bean1 = (AccountService) ac.getBean("accountService1");
AccountService bean2 = (AccountService) ac.getBean("accountService2");
AccountService bean3 = (AccountService) ac.getBean("accountService3");
AccountService bean4 = (AccountService) ac.getBean("accountService4");
System.out.println(bean1);
System.out.println(bean2);
System.out.println(bean3);
System.out.println(bean4);
}
结果:
appName:假发;
count:100
appName:程序员;
count:1000000
appName:戴假发;
count:999
appName:有假发;
count:99
1.25 ref注入引用对象
当我们通知spring帮我们注入某个引用来行的对象时,我们可以使用ref通知spring注入bean的beanName。
案例:
我们有AccountDAO和AccountService类:
/**
* @author 戴着假发的程序员
*
* @description
*/
public class AccountDAO implements IAccountDAO {
@Override
public int save(String name) {
System.out.println("AccountDAO-save:"+name);
return 1;
}
}
/**
* @author 戴着假发的程序员
*
* @description
*/
public class AccountService {
private AccountDAO accountDAO;
public void setAccountDAO(AccountDAO accountDAO) {
this.accountDAO = accountDAO;
}
// 无参构造
public AccountService(){}
//有参构造
public AccountService(AccountDAO accountDAO) {
this.accountDAO = accountDAO;
}
public int save(String name){
System.out.println("AccountService-save:"+name);
return accountDAO.save(name);
}
}
我们可以以下面的方式配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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">
<!--dao-->
<bean id="accountDAO1" class="com.boxuewa.dk.demo2.dao.impl.AccountDAO"/>
<!-- service方式1-->
<bean id="accountService1" class="com.boxuewa.dk.demo2.service.AccountService">
<property name="accountDAO" ref="accountDAO1"/>
</bean>
<!-- service方式2-->
<bean id="accountService1" class="com.boxuewa.dk.demo2.service.AccountService">
<property name="accountDAO"><ref bean="accountDAO1"/></property>
</bean>
<!-- service方式3-->
<bean id="accountService1" class="com.boxuewa.dk.demo2.service.AccountService">
<constructor-arg name="accountDAO" ref="accountDAO1"/>
</bean>
<!-- service方式4-->
<bean id="accountService1" class="com.boxuewa.dk.demo2.service.AccountService">
<constructor-arg name="accountDAO"><ref bean="accountDAO1"/></constructor-arg>
</bean>
<!-- service方式5-->
<bean id="accountService1" class="com.boxuewa.dk.demo2.service.AccountService">
<property name="accountDAO">
<bean class="com.boxuewa.dk.demo2.dao.impl.AccountDAO"/>
</property>
</bean>
<!-- service方式6-->
<bean id="accountService1" class="com.boxuewa.dk.demo2.service.AccountService">
<constructor-arg name="accountDAO">
<bean class="com.boxuewa.dk.demo2.dao.impl.AccountDAO"/>
</constructor-arg>
</bean>
</beans>
测试:
@Test
public void testRef(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService bean1 = (AccountService) ac.getBean("accountService1");
AccountService bean2 = (AccountService) ac.getBean("accountService2");
AccountService bean3 = (AccountService) ac.getBean("accountService3");
AccountService bean4 = (AccountService) ac.getBean("accountService4");
AccountService bean5 = (AccountService) ac.getBean("accountService5");
AccountService bean6 = (AccountService) ac.getBean("accountService6");
bean1.save("假发-1");
bean2.save("假发-2");
bean3.save("假发-3");
bean4.save("假发-4");
bean5.save("假发-5");
bean6.save("假发-6");
}
结果:
AccountService-save:假发-1
AccountDAO-save:假发-1
AccountService-save:假发-2
AccountDAO-save:假发-2
AccountService-save:假发-3
AccountDAO-save:假发-3
AccountService-save:假发-4
AccountDAO-save:假发-4
AccountService-save:假发-5
AccountDAO-save:假发-5
AccountService-save:假发-6
AccountDAO-save:假发-6
1.26 注入set集合
我们可以通过set标签对类中的set属性进行注入,无论属性是简单类型和引用类型。
案例:
准备账户类,拥有属性account,有参和无参构造方法
/**
* @author 戴着假发的程序员
*
* @description 账户
*/
public class Account {
private String account;
public Account(){
}
public Account(String account) {
this.account = account;
}
public void setAccount(String account) {
this.account = account;
}
@Override
public String toString(){
return "account:"+account;
}
}
准备账户组类,这个类拥有两个set集合类型的属性,一个accName存储字符串类型的账户名字,一个存储Account类型的账户对象。 拥有有参和无参构造方法。
/**
* @author 戴着假发的程序员
*
* @description
*/
public class Group {
//账户名字集合
private Set<String> accNames;
//账户对象集合
private Set<Account> accounts;
public void setAccNames(Set<String> accNames) {
this.accNames = accNames;
}
public void setAccounts(Set<Account> accounts) {
this.accounts = accounts;
}
//无参数构造
public Group(){
}
//有参数构造
public Group(Set<String> accNames, Set<Account> accounts) {
this.accNames = accNames;
this.accounts = accounts;
}
public void showNames(){
for(String name : accNames){
System.out.print(name+"\t");
}
System.out.println();
}
public void showAccount(){
for(Account account : accounts){
System.out.print(accounts);
}
System.out.println();
}
}
我们在配置文件中给group注入属性。使用set标签进行注入:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byType" 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">
<!-- 准备三个accountBean -->
<bean id="account1" class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="卡卡西"/>
</bean>
<bean id="account2" class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="佐助"/>
</bean>
<bean id="account3" class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="鸣人"/>
</bean>
<!-- 注册一个group -->
<bean id="group" class="com.dk.demo2.beans.Group">
<property name="accNames">
<!-- 使用set标签注入简单set集合属性 -->
<set>
<value>路飞</value>
<value>索隆</value>
<value>山治</value>
</set>
</property>
<property name="accounts">
<!-- set标签注入引用类型属性 -->
<set>
<ref bean="account1"/>
<ref bean="account2"/>
<ref bean="account3"/>
</set>
</property>
</bean>
</beans>
测试:
@Test
public void testSet(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
Group bean = ac.getBean(Group.class);
bean.showNames();
bean.showAccount();
}
结果:
当然对应引用类型其实我们也可以在set标签中利用bean标签直接实例化对象,例如:
<bean id="group" class="com.boxuewa.dk.demo2.beans.Group">
<property name="accNames">
<!-- 使用set标签注入简单set集合属性 -->
<set>
<value>路飞</value>
<value>索隆</value>
<value>山治</value>
</set>
</property>
<property name="accounts">
<!-- set标签注入引用类型属性 -->
<set>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="乔峰"/>
</bean>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="虚竹"/>
</bean>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="段誉"/>
</bean>
</set>
</property>
</bean>
测试结果:
注意:上面的所有注入方式也都适合构造方法的注入。例如:
<!-- 注册一个group -->
<bean id="group" class="com.dk.demo2.beans.Group">
<constructor-arg name="accNames">
<!-- 使用set标签注入简单set集合属性 -->
<set>
<value>路飞</value>
<value>索隆</value>
<value>山治</value>
</set>
</constructor-arg>
<constructor-arg name="accounts">
<!-- set标签注入引用类型属性 -->
<set>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="乔峰"/>
</bean>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="虚竹"/>
</bean>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="段誉"/>
</bean>
</set>
</constructor-arg>
</bean>
1.27 注入list集合
list集合的注入和set集合的注入基本完全相同。
案例
我们修改上面案例中的类型即可:
准备账户类,拥有属性account,有参和无参构造方法
/**
* @author 戴着假发的程序员
*
* @description 账户
*/
public class Account {
private String account;
public Account(){
}
public Account(String account) {
this.account = account;
}
public void setAccount(String account) {
this.account = account;
}
@Override
public String toString(){
return "account:"+account;
}
}
准备账户组类,这个类拥有两个set集合类型的属性,一个accName存储字符串类型的账户名字,一个存储Account类型的账户对象。 拥有有参和无参构造方法。
/**
* @author 戴着假发的程序员
*
* @description
*/
public class Group {
//账户名字集合
private List<String> accNames;
//账户对象集合
private List<Account> accounts;
public void setAccNames(List<String> accNames) {
this.accNames = accNames;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
//无参数构造
public Group(){
}
//有参数构造
public Group(List<String> accNames, List<Account> accounts) {
this.accNames = accNames;
this.accounts = accounts;
}
public void showNames(){
for(String name : accNames){
System.out.print(name+"\t");
}
System.out.println();
}
public void showAccount(){
for(Account account : accounts){
System.out.print(account);
}
System.out.println();
}
}
我们在配置文件中给group注入属性。使用list标签进行注入:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byType" 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">
<!-- 准备三个accountBean -->
<bean id="account1" class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="卡卡西"/>
</bean>
<bean id="account2" class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="佐助"/>
</bean>
<bean id="account3" class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="鸣人"/>
</bean>
<!-- 注册一个group -->
<bean id="group1" class="com.dk.demo2.beans.Group">
<property name="accNames">
<!-- 使用list标签注入简单set集合属性 -->
<list>
<value>路飞</value>
<value>索隆</value>
<value>山治</value>
</list>
</property>
<property name="accounts">
<!-- list标签注入引用类型属性 -->
<list>
<ref bean="account1"/>
<ref bean="account2"/>
<ref bean="account3"/>
</list>
</property>
</bean>
<bean id="group2" class="com.dk.demo2.beans.Group">
<property name="accNames">
<!-- 使用list标签注入简单set集合属性 -->
<list>
<value>路飞</value>
<value>索隆</value>
<value>山治</value>
</list>
</property>
<property name="accounts">
<!-- set标签注入引用类型属性 -->
<list>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="乔峰"/>
</bean>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="虚竹"/>
</bean>
<bean class="com.dk.demo2.beans.Account">
<constructor-arg name="account" value="段誉"/>
</bean>
</list>
</property>
</bean>
</beans>
测试:
@Test
public void testList(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
Group bean1 = ac.getBean("group1",Group.class);
bean1.showNames();
bean1.showAccount();
System.out.println("------------");
Group bean2 = ac.getBean("group2",Group.class);
bean2.showNames();
bean2.showAccount();
}
结果:
其余的测试和set完全一致。
1.28 注入map集合
map集合和list、set的不同是,map是双列集合。所以注入时稍有不同,但是大致一样。
要使用标签 map 和 entry。 我们看案例:
准备Account类。拥有属性account,有参和无参构造方法。
/**
* @author 戴着假发的程序员
*
* @description 账户
*/
public class Account {
private String account;
public Account(){
}
public Account(String account) {
this.account = account;
}
public void setAccount(String account) {
this.account = account;
}
@Override
public String toString(){
return "account:"+account;
}
}
准备group类,拥有两个map集合,其中一个存储账户名字(String)类型,以账号(Integer)作为key。另一个存储Account对象,以账号(Integer)作为key。并且提供有参数构造和无参数构造。
/**
* @author 戴着假发的程序员
*
* @description
*/
public class Group {
//账户名字集合
private Map<Integer,String> accNames;
//账户对象集合
private Map<Integer,Account> accounts;
public void setAccNames(Map<Integer,String> accNames) {
this.accNames = accNames;
}
public void setAccounts(Map<Integer,Account> accounts) {
this.accounts = accounts;
}
//无参数构造
public Group(){
}
//有参数构造
public Group(Map<Integer,String> accNames, Map<Integer,Account> accounts) {
this.accNames = accNames;
this.accounts = accounts;
}
public void showNames(){
System.out.println(accNames);
}
public void showAccount(){
System.out.println(accounts);
}
}
在配置文件中进行注入:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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">
<!-- 准备三个accountBean -->
<bean id="account1" class="com.boxuewa.dk.demo2.beans.Account">
<constructor-arg name="account" value="卡卡西"/>
</bean>
<bean id="account2" class="com.boxuewa.dk.demo2.beans.Account">
<constructor-arg name="account" value="佐助"/>
</bean>
<bean id="account3" class="com.boxuewa.dk.demo2.beans.Account">
<constructor-arg name="account" value="鸣人"/>
</bean>
<!-- 注册一个group -->
<bean id="group" class="com.boxuewa.dk.demo2.beans.Group">
<property name="accNames">
<!-- 使用set标签注入简单set集合属性 -->
<map>
<entry key="9527" value="路飞"/>
<entry key="9528" value="佐助"/>
<entry key="9529"><value>鸣人 </value></entry>
</map>
</property>
<property name="accounts">
<!-- set标签注入引用类型属性 -->
<map>
<entry key="110"> <ref bean="account1"/></entry>
<entry key="111"> <ref bean="account2"/></entry>
<entry key="112" value-ref="account3"/>
</map>
</property>
</bean>
</beans>
测试:
@Test
public void testMap(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
Group bean1 = ac.getBean("group1",Group.class);
bean1.showNames();
bean1.showAccount();
}
注意几个问题:
1、上面的注入方式同样适合构造方法的注入:
<!-- 注册一个group -->
<bean id="group" class="com.boxuewa.dk.demo2.beans.Group">
<constructor-arg name="accNames">
<!-- 使用set标签注入简单set集合属性 -->
<map>
<entry key="9527" value="路飞"/>
<entry key="9528" value="佐助"/>
<entry key="9529"><value>鸣人 </value></entry>
</map>
</constructor-arg>
<constructor-arg name="accounts">
<!-- set标签注入引用类型属性 -->
<map>
<entry key="110"> <ref bean="account1"/></entry>
<entry key="111"> <ref bean="account2"/></entry>
<entry key="112" value-ref="account3"/>
</map>
</constructor-arg>
</bean>
2、同样我们可以在注入bean的同时实例化:
<constructor-arg name="accounts">
<!-- set标签注入引用类型属性 -->
<map>
<entry key="110"> <ref bean="account1"/></entry>
<entry key="111"> <ref bean="account2"/></entry>
<entry key="112" value-ref="account3"/>
<entry key="112">
<bean class="com.boxuewa.dk.demo2.beans.Account">
<constructor-arg name="account" value="翠花"/>
</bean>
</entry>
</map>
</constructor-arg>
3、map的key可以是任何类型,所以其实map的可以也可使用 key-ref引用其他类型,当然就需要你自己制定一个专门的类型作为key。 这种方式我们一般都会使用。
1.29 注入props集合
props标签是用来注入java中的Properties类型的。我们知道Properties其实是继承了Hashtable,所以它也是双列集合,所以注入方式和map几乎相同,只是key和value的类型都是String,所以注入方式略有不同。看案例: 准备group类,拥有两个Properties集合,其中一个存储账户名字(String)类型,以账号(String)作为key。
/**
* @author 戴着假发的程序员
*
* @description
*/
public class Group {
//账户名字集合
private Properties accNames;
public void setAccNames(Properties accNames) {
this.accNames = accNames;
}
//无参数构造
public Group(){
}
//有参数构造
public Group(Properties accNames) {
this.accNames = accNames;
}
public void showNames(){
System.out.println(accNames);
}
}
我们在配置文件中进行注入:
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName" 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">
<!-- 注册一个group -->
<bean id="group" class="com.boxuewa.dk.demo2.beans.Group">
<property name="accNames">
<!-- 使用props标签注入简单Properties集合属性 -->
<props>
<prop key="9527">卡卡西</prop>
<prop key="9528">佐助</prop>
<prop key="9529">鸣人</prop>
</props>
</property>
</bean>
</beans>
测试:
@Test
public void testMap(){
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
Group bean1 = ac.getBean("group1",Group.class);
bean1.showNames();
}
结果:
未完待续。。。。。。欢迎关注