几种方式创建对象
-
简单对象
-
直接new创建对象()---> 基于反射完成
-
-
复杂对象
-
不能被直接new创建对象
-
接口类型的创建,不可以直接new,通过实现类来创建,这些实现类也不能直接被new出来的
-
比如Connection。
-
所以这些对象使用FactoryBean创建方式(实现FactoryBean接口)
-
getObject(),getObjectType(),isSinglenton
-
也可以根据静态工厂,实例工厂,他们俩不需要实现接口,静态工厂在xml里指定<bean factory-method,而实例工厂的方法没有static修饰,无法通过类名.创建,所有要先创建对象再使用,因此应该在XML文件中先配置实例工厂的对象,再<bean id="" factory-bean="工厂的beanName" factory-method="创建的对象的方法"
-
但是如果仅此而已的话,对于Spring来说可能就有点无用了,因为仅仅这样的话,我们得到的也就是一个简单的对象,我们还要考虑为对象的属性赋值,即注入。
注入分为几种方式:
-
set注入(最常用)程序员完成的注入(八种基本类型(value,list),自建类型注入(ref-bean)),容器自己的注入--> Aware
-
-
对象的beanName命名是在xml里的,怎么在对象内部获得beanName,通过这个对象实现BeanNameAware接口实现,那么下面这个set就是负责Spring调用执行的
-
那么同时,我想在我对象里使用当前的Bean工厂怎么办?
-
如果我们直接在对象中直接new一个工厂,我们想要获得的是当前加工bean的工厂,如果我们新new一个工厂,就相当于有两个工厂,Spring工厂是重量级资源,一种类型的工厂,我们只创建一个,同时实现BeanFactoryAware接口的方法,Spring通过调用这个方法将工厂传递给当前对象。
-
-
public class Account implements BeanNameAware, BeanFactoryAware { private String name; private String password; private String beanName; private BeanFactory beanFactory; @Override public void setBeanName(String name) { this.beanName = name; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("Account.setBeanFactory"); this.beanFactory = beanFactory; } }
-
不会发生重载 - Spring内部也是使用的set
-
可以避免循环引用。
-
-
构造注入
-
autowire 自动注入
在完成对象的创建和注入之后,Spring允许我们执行一个方法,来完成对对象的初始化,即执行初始化方法,定义的方式有两种
第一种,在对象内部随意顶一个方法,并在其中书写初始化方法。
但此时,Spring并不会知道这个方法就是这个对象的初始化方法,因此我们应该在xml文件中来告知Spring。
第二种方法,实现Spring规定的接口
并实现该接口的方法,其中书写要执行的初始化方法,不需要在xml文件中告知Spring容器,两种方法同时存在,优先执行第二种,Spring一般都会有限执行实现了他的接口的,此时,我们创建的这个对象基本上就可以被使用了。
当对象使用结束,应该对对象执行销毁操作,同样有两种方式完成,我们可以在类中定义一个销毁方法,任意名字,其中书写对象被销毁之前,要执行什么操作(释放资源的操作),比如IO流的关闭,比如把一些对象的引用置为null。
同样,我们也要告知Spring,这个对象的销毁方法是什么。
第二种,也可以去实现接口,去实现Disposablebean的接口
注意:单例对象的销毁是在Spring工厂关闭的时候执行的。
虽然,上述步骤已经可以保证用户使用对象了,但Spring还提供了BeanPostProcessor方法,来让用户可以对对象进一步的加工处理。
那这一步是不是有一些多余,为什么我不在定义对象的过程中我直接增加功能,我还要多此一举,在后置处理bean的时候在执行一次加工呢?
但注意,我们并不是只有一个对象,那么如果我想要给10个对象同时增加一个功能,比如登录验证,那么Spring工厂就可以通过BeanPostProcess来完成对所有对象的功能增加,避免了我要给10个对象附加相同的功能,避免了代码冗余,另一方面,我们附加的功能都不是这个对象要完成的主要的功能,只是次要的功能,也在一定程度上实现了解耦合。
要让Spring执行后置处理Bean,需要创建一个类并实现BeanPostProcessor接口。
before在注入之后,初始化之前被触发,after在初始化之后被触发
入参中的bean就是要被加工的对象,beanName就是id值(一般情况下,前文源码有述),返回值是被加工后的bean。
同时告知Spring