一、Bean的装配
bean的装配,即Bean对象的创建,容器根据代码要求来创建Bean对象后再传递给代码的过程,称为Bean的装配。
二、默认装配方式
代码通过getBean()方式从容器获取指定的Bean示例,容器首先会调用Bean类的无参构造器,创建空值的示例对象。
三、工厂方法设计模式(为了解耦合)
1 public class ServiceFactory { 2 public ISomeService getISomeService(){ 3 return new SomeServiceImpl(); 4 } 5 }
@Test public void test01() { ISomeService service=new ServiceFactory().getISomeService(); service.doSome(); }
静态工厂
public class ServiceFactory { public static ISomeService getISomeService(){ return new SomeServiceImpl(); } }
@Test public void test01() { ISomeService service=ServiceFactory.getISomeService(); service.doSome(); }
四、动态工厂Bean
public class ServiceFactory { public ISomeService getSomeService(){ return new SomeServiceImpl(); } }
<!--注册动态工厂 -->
<bean id="factory" class="com.jmu.ba02.ServiceFactory"></bean>
@SuppressWarnings("resource") @Test public void test02() { //创建容器对象 String resource = "com/jmu/ba02/applicationContext.xml"; ApplicationContext ac=new ClassPathXmlApplicationContext(resource); ServiceFactory factory=(ServiceFactory) ac.getBean("factory"); ISomeService service = factory.getSomeService(); service.doSome(); }
但以上方法不好。修改如下(测试类看不到工厂,也看不到接口的实现类)
<!--注册service:动态工厂Bean--> <bean id="myService" factory-bean="factory" factory-method="getSomeService"></bean>
@SuppressWarnings("resource") @Test public void test02() { //创建容器对象 String resource = "com/jmu/ba02/applicationContext.xml"; ApplicationContext ac=new ClassPathXmlApplicationContext(resource); ISomeService service = (ISomeService) ac.getBean("myService"); service.doSome(); }
五、静态工厂Bean
public class ServiceFactory { public static ISomeService getSomeService(){ return new SomeServiceImpl(); } }
<!--注册动态工厂 :静态工厂Bean-->
<bean id="myService" class="com.jmu.ba03.ServiceFactory" factory-method="getSomeService"></bean>
@Test @SuppressWarnings("resource") public void test02() { //创建容器对象 String resource = "com/jmu/ba03/applicationContext.xml"; ApplicationContext ac=new ClassPathXmlApplicationContext(resource); ISomeService service = (ISomeService) ac.getBean("myService"); service.doSome(); }
六、Bean的装配
1、Singleton单例模式:
2、原型模式prototype:
3、request:对于每次HTTP请求,都会产生一个不同的Bean实例
4、Session:对于每次不同的HTTP session,都会产生一个不同的Bean实例
七、Bean后处理器
bean后处理器是一种特殊的Bean,容器中所有的Bean在初始化时,均会自动执行该类的两个方法,由于该Bean是由其他Bean自动调用执行,不是程序员手动创建,所有Bean无需id属性。
需要做的是,在Bean后处理器类方法中,只要对Bean类与Bean类中的方法进行判断,就可以实现对指定的Bean的指定方法进行功能扩展和增强。方法返回的Bean对象,即是增强过的对象。
代码中需要自定义Bean后处理下类,该类就是实现了接口BeanPostProcessor的类。该接口包含2个方法,分别在目标Bean初始化完毕之前和之后执行,它们的返回值为:功能被扩展或增强后的Bean对象。
1 import org.springframework.beans.BeansException; 2 import org.springframework.beans.factory.config.BeanPostProcessor; 3 4 public class MyBeanPostProcessor implements BeanPostProcessor { 5 //bean:表示当前正在进行初始化的Bean对象 6 //beanName:表示当前正在进行初始化的Bean对象的id 7 @Override 8 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 9 // TODO Auto-generated method stub 10 System.out.println("执行before"); 11 return bean; 12 } 13 @Override 14 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 15 // TODO Auto-generated method stub 16 System.out.println("执行after"); 17 return bean; 18 } 19 20 21 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd"> 7 8 <bean id="myService" class="com.jmu.ba05.SomeServiceImpl"></bean> 9 <!--注册bean后处理器 --> 10 <bean class="com.jmu.ba05.MyBeanPostProcessor"></bean> 11 </beans>
输出:
1 执行doSome()方法 2 log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). 3 log4j:WARN Please initialize the log4j system properly. 4 执行before 5 执行after 6 执行doSome()方法
八、Bean后处理器的应用
要求:增强service的doSome()
1 public interface ISomeService { 2 String doSome(); 3 String doOther(); 4 }
1 public class SomeServiceImpl implements ISomeService { 2 3 @Override 4 public String doSome() { 5 // TODO Auto-generated method stub 6 System.out.println("执行doSome()方法"); 7 return "abcd"; 8 } 9 10 @Override 11 public String doOther() { 12 // TODO Auto-generated method stub 13 System.out.println("执行doOther()方法"); 14 return "fight"; 15 } 16 17 }
1 import java.lang.reflect.InvocationHandler; 2 import java.lang.reflect.Method; 3 import java.lang.reflect.Proxy; 4 5 import org.springframework.beans.BeansException; 6 import org.springframework.beans.factory.config.BeanPostProcessor; 7 8 public class MyBeanPostProcessor implements BeanPostProcessor { 9 //bean:表示当前正在进行初始化的Bean对象 10 //beanName:表示当前正在进行初始化的Bean对象的id 11 @Override 12 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 13 // TODO Auto-generated method stub 14 System.out.println("执行before"); 15 return bean; 16 } 17 @Override 18 public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { 19 // TODO Auto-generated method stub 20 System.out.println("执行after"); 21 if ("myService".equals(beanName)) { 22 Object obj = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), 23 new InvocationHandler() { 24 25 @Override 26 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 27 Object invoke = method.invoke(bean, args); 28 if ("doSome".equals(method.getName())) { 29 // TODO Auto-generated method stub 30 return ((String) invoke).toUpperCase(); 31 } 32 return invoke; 33 } 34 }); 35 //类加载器:bean.getClass().getClassLoader() 36 //final:内部类使用外部类的成员变量,外部成员变量需要为fianl 37 return obj; 38 } 39 return bean; 40 } 41 42 43 }
1 <bean id="myService" class="com.jmu.ba05.SomeServiceImpl"></bean> 2 <bean id="myService2" class="com.jmu.ba05.SomeServiceImpl"></bean> 3 <!--注册bean后处理器 --> 4 <bean class="com.jmu.ba05.MyBeanPostProcessor"></bean>
1 @SuppressWarnings("resource") 2 @Test 3 public void test02() { 4 //创建容器对象 5 String resource = "com/jmu/ba05/applicationContext.xml"; 6 ApplicationContext ac=new ClassPathXmlApplicationContext(resource); 7 ISomeService service=(ISomeService) ac.getBean("myService"); 8 System.out.println(service.doSome()); 9 System.out.println(service.doOther()); 10 11 System.out.println("--------------------"); 12 13 ISomeService service2=(ISomeService) ac.getBean("myService2"); 14 System.out.println(service2.doSome()); 15 System.out.println(service2.doOther()); 16 }
输出:
执行doSome()方法 log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment). log4j:WARN Please initialize the log4j system properly. 执行before 执行after 执行before 执行after 执行doSome()方法 ABCD 执行doOther()方法 fight -------------------- 执行doSome()方法 abcd 执行doOther()方法 fight
九、定制Bean的生命周期始末
十、id与name属性
name可以包含各种字符,id的命名必须以字母开头。