Bean的装配之动态工厂Bean、静态工厂Bean、Bean后处理器的应用、定制Bean的生命始末、bean标签的id属性与name属性
【IPersonService】
package com.athl.service;
public interface IPersonService {
String doFirst();
void doSecond();
Double doThird();
}
【PersonServiceImpl】
package com.athl.service;
public class PersonServiceImpl implements IPersonService {
public PersonServiceImpl(){
System.out.println("===PersonServiceImpl===");
}
@Override
public String doFirst() {
System.out.println("执行doFirest()方法");
return "Hello World!";
}
@Override
public void doSecond() {
System.out.println("执行doSecond()方法");
}
@Override
public Double doThird() {
System.out.println("执行doThird()方法");
return 0.00;
}
public void initAfter(){
System.out.println("初始化之后");
}
public void preDestroy(){
System.out.println("销毁之前");
}
}
【ServiceFactory】
package com.athl.utils;
import com.athl.service.IPersonService;
import com.athl.service.PersonServiceImpl;
public class ServiceFactory {
//动态工厂
public IPersonService getPersonService(){
return new PersonServiceImpl();
}
//静态工厂
public static IPersonService getStaticPersonService(){
return new PersonServiceImpl();
}
}
【applicationContext.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">
<!-- 以上约束到docs/spring-framework-reference/html/xsd-configuration.html复制 -->
<!-- 添加提示:window->preferences->查找xml->xml Catalog->User specifiled Entries
->add->引入schema\beans\spring-beans-4.2.xsd -->
<!-- 动态工厂Bean -->
<bean id="serviceFactory" class="com.athl.utils.ServiceFactory"/>
<!-- 为降低耦合度(降低类与类的耦合度) -->
<bean id="personService" factory-bean="serviceFactory" factory-method="getPersonService" />
<!-- 静态工厂Bean -->
<bean id="personStaticService" class="com.athl.utils.ServiceFactory" factory-method="getStaticPersonService" />
<!-- Bean 作用范围-->
<!--scope="prototype"原型模式
真正使用时才创建,每次获取都会创建不同的对象
scope="singleton"单例模式
容器初始化时就创建,每次获取的都是同一个对象.默认
-->
<bean id="personStaticService_Prototype" class="com.athl.utils.ServiceFactory" factory-method="getStaticPersonService" scope="prototype"/>
<!-- 注册Bean后处理器(无id,是容器自动调用的) -->
<bean class="com.athl.beanPostProcessor.MyBeanPostProcessor" />
<!-- 注册Bean生命始末 -->
<bean id="initAndDestroy" class="com.athl.service.PersonServiceImpl" init-method="initAfter" destroy-method="preDestroy" />
<!-- <bean/>标签的id属性与name属性 -->
<!--
一般情况下,用id不用name,因为id是唯一的。
在没用id的情况下,name的作用与id是相同的。
当<bean/>标签中含有特殊字符时,就需要使用name了。
两者命名规则不同:
id:遵循xml对id的命名规范,字母开头,可以包含字母数字下划线连字符句号冒号,容器内名称唯一。
name:各种字符,名称可以相同。若相同,则后面覆盖前面。
-->
</beans>
【test】
package com.athl.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.athl.service.IPersonService;
public class Mytest {
@Test
public void test02(){
/*加载Spring配置文件,创建Spring容器对象,找的是src根目录下配置文件*/
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
/*从容器中获取指定Bean对象*/
/*这样做仍没有降低耦合度*/
//ServiceFactory factory = (ServiceFactory) ac.getBean("serviceFactory");
//IPersonService service = factory.getPersonService();
/*降低了耦合度*/
System.out.println("===动态工厂===");
IPersonService service = (IPersonService) ac.getBean("personService");
service.doFirst();
service.doSecond();
System.out.println("===静态工厂===");
IPersonService serviceStatic = (IPersonService) ac.getBean("personStaticService");
serviceStatic.doFirst();
serviceStatic.doSecond();
System.out.println("===Bean的作用范围===");
IPersonService serviceStatic_Prototype = (IPersonService) ac.getBean("personStaticService_Prototype");
IPersonService serviceStatic_Prototype2 = (IPersonService) ac.getBean("personStaticService_Prototype");
System.out.println(serviceStatic_Prototype);
System.out.println(serviceStatic_Prototype2);
System.out.println("===Bean后处理器的应用===");
IPersonService serviceStatic_BeanPostProcessor = (IPersonService) ac.getBean("personStaticService");
String str = serviceStatic_BeanPostProcessor.doFirst();
System.out.println("Hello World! => "+str);
serviceStatic_BeanPostProcessor.doSecond();
serviceStatic_BeanPostProcessor.doThird();
/*销毁方法的执行有两个条件:
* 1.被销毁的对象需要是singleton的,即单例的.
* 2.容器要显示关闭
*/
((ClassPathXmlApplicationContext)ac).close();
}
}
【控制台结果打印】
一月 17, 2017 9:04:25 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6efed938: startup date [Tue Jan 17 09:04:25 GMT+08:00 2017]; root of context hierarchy
一月 17, 2017 9:04:25 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]*/
===postProcessBeforeInitialization===
===postProcessAfterInitialization===
===PersonServiceImpl===
===postProcessBeforeInitialization===
===postProcessAfterInitialization===
===PersonServiceImpl===
===postProcessBeforeInitialization===
===postProcessAfterInitialization===
===PersonServiceImpl===
===postProcessBeforeInitialization===
初始化之后
===postProcessAfterInitialization===
===动态工厂===
执行doFirest()方法
执行doSecond()方法
===静态工厂===
执行doFirest()方法
===Before===hello world!
===After===HELLO WORLD!
执行doSecond()方法
===Bean的作用范围===
===PersonServiceImpl===
===postProcessBeforeInitialization===
===postProcessAfterInitialization===
===PersonServiceImpl===
===postProcessBeforeInitialization===
===postProcessAfterInitialization===
com.athl.service.PersonServiceImpl@55f972f
com.athl.service.PersonServiceImpl@46be916a
===Bean后处理器的应用===
执行doFirest()方法
===Before===hello world!
===After===HELLO WORLD!
Hello World! => HELLO WORLD!
执行doSecond()方法
执行doThird()方法
一月 17, 2017 9:04:25 上午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@6efed938: startup date [Tue Jan 17 09:04:25 GMT+08:00 2017]; root of context hierarchy
销毁之前