spring学习----AOP

本文深入解析了Spring AOP的工作原理,介绍了核心概念如通知、切点和通知器,并详细分析了ProxyFactoryBean类如何实现AOP功能,通过创建代理对象来实现对目标对象的增强。

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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值