【sping揭秘】5、IOC容器(一)
OC容器实现过程
1、 容器启动阶段,读取配置文件,解析文件BeanDefinitionReader
2、 Bean 实例化阶段
关于BeanFactoryPostProcessor
插手spring的启动插入自己的逻辑,在第一阶段和第二阶段之间插入。。。
IOC容器中bean的操作
1、bean的实例化与BeanWarpper
容器在内部实现的时候,采用策略模式来决定如何初始化bean
策略模式:http://www.cnblogs.com/cutter-point/p/5259874.html
Spring一般使用cglib动态字节码技术实现创建一个bean实例
关于beanwarpper,就是一个用来包裹我们使用的类的类,用以节省我们操作的方便,这里通过一个案例展示
@Test public void testBeanWapper() { try { Object mo = Class.forName("cn.cutter.start.bean.MyObject").newInstance(); //使用beanwrapper进行包裹类 BeanWrapper moWrapper = new BeanWrapperImpl(mo); //设置值 moWrapper.setPropertyValue("name", "cutter_point"); moWrapper.setPropertyValue("phoneNumber", "有本事你打110"); MyObject mo1 = (MyObject) mo; System.out.println("1->" + mo1.getName() + "\n1->" + mo1.getPhoneNumber()); System.out.println("2->" + moWrapper.getPropertyValue("name") + "\n2->" + moWrapper.getPropertyValue("phoneNumber")); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
展示结果:
很方便,这样我们就免得写反射代码再去设置了
2、 InitializingBean
对象实现这个接口之后,spring会在实例化对象之后,立马调用这个方法,我们可以定义一个线程,在这个类实例化之后,定时清理缓存
package cn.cutter.start.bean; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; @Component public class MyObject implements InitializingBean { private String name; private String phoneNumber; public MyObject() { System.out.println("MyObjec construct!"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @Override public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub System.out.println("we do initializingbean afterpropertiesset !"); } }
Spring运行结果
@Test public void test4() { ApplicationContext ctx = before(); AwareTestBean awareTestBean = (AwareTestBean) ctx.getBean("awareTestBean"); AwareTestBean awareTestBean2 = (AwareTestBean) awareTestBean.getBean("awareTestBean"); // AwareTestBean awareTestBean3 = new AwareTestBean(); // AwareTestBean awareTestBean4 = (AwareTestBean) awareTestBean3.getBean("awareTestBean"); System.out.println(awareTestBean); System.out.println(awareTestBean2); // System.out.println(awareTestBean3); // System.out.println(awareTestBean4); }
不要在意里面的其他代码,注解掉也无所谓,不在这次的演示范围内,其实我们只需要运行第一行代码,也就是其中的before()函数,好吧,我再把before函数发出来
public ApplicationContext before() { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:application-bean.xml"); return ctx; }
展示结果:
先执行构造函数,然后执行afterPropertiesSet