对于对象而言,可以分为简单对象和复杂对象;
简单对象
简单对象指可以直接new的对象;
Spring在创建这些对象时,是基于反射来完成的。
复杂对象
复杂对象指不能直接new的对象。
比如:要得到接口类型的对象,是不能直接new的,需要使用其实现类来创建。但是有的其实现类也是不能直接new的,比如Connection对象。
对于这种对象,可以使用实现FactoryBean接口的方式来创建;
需要实现三个方法:
getObject() ------> 书写位置 -----> Spring工厂 回调 getObject()获得对象
getObjectType()
isSingleton()
也可以使用静态工厂或者实例工厂来创建;
静态工厂:
MyFactory{
public static Object getObject(){
xxxx
xxxxx
}
}
<bean id="" class="xxx.MyFactory" factory-method="getObject"/>
实例工厂:
MyFactory{
public Object getObject(){}
}
<bean id="myFactory" class="xxx.MyFactory"/>
<bean id="product" factory-bean="myFactory" factory-method="getObject"/>
这仅仅完成了对象的创建。我们还要考虑为对象属性进行赋值(也称为属性的注入)。
注入的方式:
set注入
<bean id="u" class="">
<property > ----------set注入
</bean>
会有两种注入的形式
程序员自己完成的注入
可以注入8种基本类型、自建类型(通过ref=)的bean;
Spring容器自己的注入(aware)
实现BeanNameAware接口,实现void setBeanName(String name)方法,Spring容器自动调用它【谁调用谁就会传参】,可以获取当前对象在工厂中的id(beanName),定义一个变量把它存起来就可以了;
实现BeanFactoryAware接口,实现void setBeanFactory(BeanFactory beanFactory)方法,Spring容器自动调用它,可以获取创建当前对象的工厂对象,定义一个变量把它存起来就可以了。
BeanFactoryAware接口的应用场景:
可以解决scope=prototype在注入过程中失效的问题。
比如类A是单例的,类B是多例的,类A中有类B的成员变量b,如果用set注入,每一次获取都是一样的地址,因为类A对象已经被创建出来,并存储到容器里了,再获取成员变量b时,没有为其重新赋值。
我们可以获取到工厂,每次在a中使用b时,都从容器中获取一次。
scope=prototype在注入过程中失效的解决方式还有一个,lookup-method = ,但是用的少
这两种方式先后顺序是怎样的呢?——用户自己设置的set注入在前,容器的注入在后。
构造注入
<bean id="u" class="">
<constructor-arg >——————构造注入
</bean>
autowire自动注入
如果在beans配置,beans管理的所有bean都会自动注入
如果在bean配置,此bean的属性会自动注入;
问题:为什么还需要实现BeanPostProcessor接口为其增加功能,不能在创建对象时,直接写好呢?
答案:BeanPostProcessor接口中的方法,可以为多个对象增加功能,代码可以复用,减少代码的冗余;
加功能是可有可无的功能,如果需要可以加上,如果不需要就取消掉,可以解决代码的耦合。
问题:一般在BeanPostProcessor接口的哪个方法为对象增加功能呢?
答案:postProcessAfterInitialization方法,因为前面已经初始化完成了,后续没有在对bean的操作了;如果在postProcessBeforeInitialization中为对象进行加工,后续可能还会改。
注意:BeanPostProcessor的功能,只有在高级的工厂(比如ApplicationContext)才有。
注意:第5步的初始化操作,和BeanPostProcessor的方法,在开发中我们一般不用。
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(""));
beanFactory.getBean("id");
第一行代码的作用:
读取xml文件,解析bean标签,封装成BeanDefinition对象,并以id为key,BeanDefinition对象为value存储到map中;
第二行代码的作用:
1.基于BeanDefinition创建对象;
2.创建对象的过程,包括前文生命周期中除销毁的步骤;
3.创建对象的过程中,需要按照scope进行讨论:
scope=singleton——单例对象,Spring中使用map结构(key为bean的id,value为bean)来保证永远只创建一次;
scope=prototype——每次都走一遍创建对象的流程。
性能优化是个系统性工程,宏观上可分为网络,服务,存储几个方向,每个方向又可以细分为架构,设计,代码,可用性,度量等多个子项。 本文将重点从代码和设计两个子项展开,谈谈那些提升性能的知识点。