AOP概念
advice(通知)做什么事(before、after、afterReturing、afterThrowing等等)
pointcut(切点):什么地方
advisor(通知器):使用那个通知(advice),在那个切点使用(pointcut)
spring AOP继承关系
- ProxyConfig 数据基类
- AdvisedSupport 封装通知、通知器操作
- ProxyCreatorSupport 子类创建代理对象的辅助类
- ProxyFactoryBean springAOP应用 代理对象生成的具体类 (可以使用声明式配置)
- ProxyFactory springAOP应用 代理对象生成的具体类 (编程式使用springAOP功能)
- AspectJProxyFactory 代理对象生成 继承spring和AspectJ
以ProxyFactoryBean 为例说明
public class ProxyFactoryBean extends ProxyCreatorSupport implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware
- 实现 FactoryBean通过getObject方法获取代理对象
- 实现 BeanClassLoaderAware 获取当前容器的classLoader JDKDynamicProxy必要参数
- 实现 BeanFactoryAware 获取beanFactory
源码分析
AbstractBeanFactory类
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 从缓存中获取已实例化的bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 对获取的实例处理 如果没有继承FactoryBean直接返回实例
// 否则调用getObject aop的代理对象的生成入口就在此处
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
FactoryBeanRegistrySupport
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// AOP代理对象生成
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
ProxyFactoryBean
public Object getObject() throws BeansException {
//初始化通知器
this.initializeAdvisorChain();
if(this.isSingleton()) {
return this.getSingletonInstance();
} else {
if(this.targetName == null) {
this.logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the \'targetName\' property.");
}
return this.newPrototypeInstance();
}
}
ProxyCreatorSupport
protected final synchronized AopProxy createAopProxy() {
if(!this.active) {
this.activate();
}
return this.getAopProxyFactory().createAopProxy(this);
}
DefaultAopProxyFactory
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if(!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class targetClass = config.getTargetClass();
if(targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
// 使用何种方式生成代理对象
// 继承接口的方式使用jdk动态代理
// 否则使用cglib
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass)?new ObjenesisCglibAopProxy(config):new JdkDynamicAopProxy(config));
}
}
}
AOP ProxyFactoryBean示例
bean xml配置
<!-- ======================spring AOP配置=========================================-->
<bean id="myBeforeAdvice" class="com.chenfei.advice.MyBeforeAdvice"></bean>
<bean id="bussinessService" class="com.chenfei.service.impl.BussinessServiceImpl"></bean>
<bean id="myProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.chenfei.service.IBussinessService</value>
</property>
<property name="target">
<ref bean="bussinessService"/>
</property>
<property name="interceptorNames">
<list>
<value>myBeforeAdvice</value>
</list>
</property>
</bean>
advice
public class MyBeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("=========我是前置通知方法=============");
}
}
需要生成代理类的接口
public interface IBussinessService {
void bussiness();
void sayHello();
}
需要生成代理类的目标对象
public class BussinessServiceImpl implements IBussinessService{
@Override
public void bussiness() {
System.out.println("=========我是业务方法==========");
}
@Override
public void sayHello() {
System.out.println("=========我是say Hello==========");
}
}
测试方法
public class TestSpringAOP {
@Test
public void test(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:beans.xml");
IBussinessService bussinessServiceImpl = applicationContext.getBean("myProxy",IBussinessService.class);
bussinessServiceImpl.bussiness();
bussinessServiceImpl.sayHello();
}
}
本文深入解析了Spring AOP的工作原理,介绍了核心概念如通知、切点和通知器,并详细分析了ProxyFactoryBean类如何实现AOP功能,通过创建代理对象来实现对目标对象的增强。
1316

被折叠的 条评论
为什么被折叠?



