三、认识FactoryBean
3.1、介绍FactoryBean与BeanFactory的区别
Spring中有两种Bean
在Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,也就是FactoryBean。这两种Bean都被容器管理,但是工程Bean跟普通Bean不同,其返回的对象不是特定类的一个实例,其返回的是该FactoryBean的getObject()方法所返回的对象。
在Spring框架内部有很多地方有FactoryBean的实现类,在很多应用如:Spring的AOP、ORM、事务管理以及其他第三方框架(hibernate、mybatis、jpa集成都有体现)
分辨BeanFactory与FactoryBean区别
BeanFactory:以Factory结尾,表示它是一个工厂类,是用来管理Bean的一个工厂。
是一个Spring容器,是一个大型工厂,可以生产出各种各样的Bean。
FactoryBean:以Bean结尾,表示它是一个Bean,不同于普通Bean的是,其实现了FactoryBean接口的Bean,根据该Bean的id从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,若是要获取FactoryBean的对象可以根据&id名来获取。
本身是一个Bean,同时它相当于一个小型工厂,可以生产出另外的Bean(getObject()中获取)。
3.2、认识FactoryBean
getObject():返回的是Bean对象。
getObjectType():返回的是Bean对象类型。
boolean isSingleton():返回是否为单例,默认是true,表示单例。
FactoryBean:其是Spring所提供的一种较灵活的创建Bean的方式,可以通过实现FactoryBean接口中的getObject()方法来返回一个对象,这个对象就是最终的Bean对象。
3.3、自定义一个FactoryBean
自动配置类
@Configuration @ComponentScan("xyz.changlu") //自动扫描xyz.changlu包目录下 public class SpringConfig { }
User类:下面自定义FactoryBean实际创建得到的一个bean
public class User { }
自定义FactoryBean类:
@Component("clfb") //这里设置name为clfb。(若是没有自定义参数,那么就会name为changluFactoryBean) public class ChangluFactoryBean implements FactoryBean { //实现FactoryBean接口,并重写两个方法 //返回的实际bean对象,其name为clfb @Override public Object getObject() throws Exception { return new User(); } //返回bean对象的类型 @Override public Class<?> getObjectType() { return User.class; } }
测试类:
public class Main{ public static void main(String[] args) throws IOException { ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class); //FactoryBean实现类会创建两个Bean对象 //获取到ChangluFactoryBean创建的bean对象 Object bean = applicationContext.getBean("clfb"); System.out.println(bean); //获取到ChangluFactoryBean这个bean对象 Object clfb = applicationContext.getBean("&clfb"); System.out.println(clfb); } }
运行测试类得到以下结果:
总结:对于上面的FactoryBean实际上对应了两个Bean对象:
beanName为"clfb",bean对象为getObject方法所返回的User对象。
beanName为"&clfb",bean对象为ChangluFactoryBean类的实例对象。
四、认识ApplicationContext
ApplicationContext:该接口是比BeanFactory更加强大的Spring容器,它既可以创建bean、获取bean,还支持国际化、事件广播、获取资源等BeanFactory不具备的功能。(该接口多继承了多个接口其中就包含了BeanFactory)
介绍ApplicationContext继承的接口
EnvironmentCapable(环境能力):表示拥有获取环境变量的功能,可以通过ApplicationContext获取操作系统环境变量和JVM环境变量。
HierarchicalBeanFactory(分层):拥有获取父BeanFactory、判断某个name是否存在bean对象的功能。
ListableBeanFactory(清单):拥有获取所有beanNames、判断某个beanName是否存在beanDefinition对象、统计BeanDefinition个数、获取某个类型对应的所有beanNames等功能。(获取bean名称、是否存在bean、个数、类型)
ApplicationEventPublisher:拥有事件发布功能,可以发布事件,这是ApplicationContext相对于BeanFactory比较突出、常用的功能。
ResourcePatternResolver:拥有加载并获取资源的功能,这里的资源可以是文件,图片等某个URL资源。
MessageSource:拥有国际化功能,比如可以直接利用MessageSource对象获取某个国际化资源(比如不同国家语言所对应的字符)
五、认识BeanPostProcessor
BeanPostProcessor是Spring所提供的一种扩展机制,可以利用该机制对Bean进行定制化加工,在Spring底层源码实现中,也广泛使用了该机制,BeanPostProcessor通常也叫做Bean后置处理器。
BeanPostProcessor:在Spring中是一个接口,我们定义一个后置处理器(实现该接口即可),在Spring中还存在一些接口继承了BeanPostProcessor,这些子接口是在BeanPostProcessor的基础上增加了一些其他功能。
postProcessBeforeInitialization():初始化前方法,表示可以利用这个方法来对Bean在初始化前进行自定义加工。
postProcessAfterInitialization():初始化后方法,利用这个方法来对Bean在初始化后进行自定义加工。
介绍子接口(扩展功能):InstantiationAwareBeanPostProcessor
首先看一些Bean后置处理器接口有哪些子类接口与实现类:
我们来其中子接口InstantiationAwareBeanPostProcessor中的方法:主要看其中三个方法,有一个已经过时
postProcessBeforeInstantiation():实例化前。
postProcessAfterInstantiation():实例化后。
postProcessProperties():属性注入后。
这个接口相较于BeanPostProcessor更强大具有实例化前后、属性注入后的方法功能。
AOP是如何工作的?
介绍AOP与六个核心概念
AOP:就是面向切面编程,是一种非常适合在无需修改业务代码的前提下,对某个或某些业务增加统一的功能,比如日志记录、权限控制、事务管理等,能很好的使代码解耦,提高开发效率。
其包含六个核心概念:
Advice:通知、建议,在Spring中通过定义Advice来定义代理逻辑。
Pointcut:切点,表示Advice对应的代理逻辑应用到哪个类、哪个方法上。
Advisor:Advice+Pointcut,表示代理逻辑和切入点的一个整体,程序员可通过定义或封装一个Advisor,来定义切点和代理逻辑。
Weaving织入,将Advice代理逻辑在源代码级别嵌入到切点的过程。
Target:表示目标对象,也就是被代理对象,在AOP生成的代理对象中会持有目标对象。
Join Point:表示连接点,在Spring AOP中,就是方法的执行点。
AOP的工作原理
AOP是发生在Bean的生命周期过程中的:
Spring生成bean对象时,先实例化出来一个对象,也就是target对象。
接着对target对象进行属性填充。
在初始化后步骤中,会判断target对象有没有对应的切面。
如果有切面,就表示当前target对象需要进行AOP。
通过Cglib或JDK动态代理机制生成一个代理对象,作为最终的bean对象。
在代理对象中有一个target属性指向target对象。