spring-aop-ProxyFactoryBean 源码分析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

在阅读本篇之前,请先阅读[url]http://wangxinchun.iteye.com/blog/2079024\[/url\],重复的逻辑,本篇不再进行分析

在spring框架有一个鲜明的特点,一般的服务 都有编程式的和配置式的两种实现。

编程方式的使用往往比较明了,但是功能相对弱,使用不够简洁。配置式的往往能结合spring的ioc框架,提供更松散更强大的功能,兼容并蓄在spring框架在所有方面都表现的淋漓尽致。

相对于ProxyFactory 实现AOP拦截的方式,ProxyFactoryBean 是通过配置实现所有拦截功能。

使用case:

业务类


    public interface LoginService {
        public boolean login(User user);
    }
    public class LoginServiceImpl implements LoginService {
        public boolean login(User user) {
            System.out.println(user);
            if (user == null) {
                return false;
            } else if (user.getUsername() == "xinchun.wang" && user.getPassword() == "123456") {
                return true;
            }
            return false;
        }
    }

增强(Advice,Interceptor)


    public class AfterAdvice1 implements AfterReturningAdvice{
        public void afterReturning(Object returnValue, Method method,
                Object[] args, Object target) throws Throwable {
            System.out.println("AfterAdvice1.afterReturning() execute ");
        }
    }
    public class AfterAdvice2 implements AfterReturningAdvice{
        public void afterReturning(Object returnValue, Method method,
                Object[] args, Object target) throws Throwable {
            System.out.println("AfterAdvice2.afterReturning() execute ");
        }
    }

    public class BeforeAdvice1 implements MethodBeforeAdvice{
        public void before(Method method, Object[] args, Object target)
                throws Throwable {
            System.out.println("BeforeAdvice1.before() execute ");
        }
    }
    public class BeforeAdvice2 implements MethodBeforeAdvice{
        public void before(Method method, Object[] args, Object target)
                throws Throwable {
            System.out.println("BeforeAdvice2.before() execute ");
        }
    }

其他辅助工具代码:


    public class BeanFactoryUtils implements BeanFactoryAware{
        private static BeanFactory beanFactory;
        public static BeanFactoryUtils getInstance(){
            return (BeanFactoryUtils)beanFactory.getBean("factoryUtil");
        }
        public void setBeanFactory(BeanFactory bf) throws BeansException {
            beanFactory = bf;       
        }
        public BeanFactory getBeanFactory() {
            return beanFactory;
        }
    }

applicationContext.xml 配置


    <bean id="afterAdvice1" class="com.qunar.service.AfterAdvice1" />
        <bean id="afterAdvice2" class="com.qunar.service.AfterAdvice2" />
        <bean id="beforeAdvice1" class="com.qunar.service.BeforeAdvice1" />
        <bean id="beforeAdvice2" class="com.qunar.service.BeforeAdvice1" />
    <bean id="loginService" class="com.qunar.service.LoginServiceImpl"/>
        <bean id="factoryUtil" class=" com.qunar.util.BeanFactoryUtils" />
        <bean id="loginServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            <!--这里代理的是接口 -->
            <property name="proxyInterfaces">
                <value> com.qunar.service.LoginService</value>
            </property>
            <!--是ProxyFactoryBean要代理的目标类 -->
            <property name="target">
                <ref bean="loginService" />
            </property>
            <!--程序中的Advice -->
            <property name="interceptorNames">
                <list>
                    <value>afterAdvice1</value>
                    <value>afterAdvice2</value>
                    <value>beforeAdvice1</value>
                    <value>beforeAdvice2</value>
                </list>
            </property>
        </bean>

测试:


    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = { "classpath*:META-INF/spring/applicationContext.xml"})
    public class LoginServiceImplTest {
        @Test
        public void proxyLoginTest() {
            LoginService loginService = (LoginService)BeanFactoryUtils.getInstance().getBeanFactory().getBean("loginServiceProxy");
            loginService.login(new User("xinchun.wang","123456"));
        }
    }

输出:

BeforeAdvice1.before() execute

BeforeAdvice1.before() execute

com.qunar.vo.User@111b910

AfterAdvice2.afterReturning() execute

AfterAdvice1.afterReturning() execute

概述:

ProxyFactoryBean 在继承体系上和ProxyFactory并没有太多差异,但是ProxyFactoryBean实现了 BeanFactoryAware BeanClassLoaderAware FactoryBean 三个接口,熟悉IOC容器的话,可以知晓ProxyFactoryBean 和IOC容器有了交融的地方了,ProxyFactoryBean 正是借助IOC容器的配置,找到Advice增强和target对象。

下面进入源码剖析


    public class ProxyFactoryBean extends ProxyCreatorSupport
            implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {

        /**
         * interceptor 名字的通配符
         */
        public static final String GLOBAL_SUFFIX = "*";

        protected final Log logger = LogFactory.getLog(getClass());
      //拦截器的名字
        private String[] interceptorNames;
        //代理对象的名字
        private String targetName;

        private boolean autodetectInterfaces = true;

        private boolean singleton = true;
        //这个类在ProxyFactory 已经说过了,可以参考下。是做拦截器的解析的。
        private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

        private boolean freezeProxy = false;

        private transient ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();

        private transient boolean classLoaderConfigured = false;
      //IOC容器
        private transient BeanFactory beanFactory;

        /** Whether the advisor chain has already been initialized */
        private boolean advisorChainInitialized = false;

        /** 如果但是,singletonInstance 可以缓存  */
        private Object singletonInstance;

        /**
         * 设置代理的接口,如果没有设置,那么会用cglib2做代理。
         */
        public void setProxyInterfaces(Class[] proxyInterfaces) throws ClassNotFoundException {
            setInterfaces(proxyInterfaces);
        }

        /**
          设置interceptorNames 拦截器的名字,但是这些名字必须在IOC容器里注册了。
          interceptorNames 对应的名字的类型可以是 Interceptor, Advisor or Advice,
          最后一项可以是IOC容器中的任何一个,如果他不是Advice 也不是 Advisor,会使用
          SingletonTargetSource 进行包装这个对象,如果 target 或者 targetSource 或者targetName
          设置了,那么 interceptorNames 只能包含 Advice/Advisor bean names.*/

        public void setInterceptorNames(String[] interceptorNames) {
            this.interceptorNames = interceptorNames;
        }

        /**
         * 设置targetname
         */
        public void setTargetName(String targetName) {
            this.targetName = targetName;
        }

        /**
         * 设置是否自动检测接口,默认是true,如果为false,那么所有的借口都是cglib来代理。
         */
        public void setAutodetectInterfaces(boolean autodetectInterfaces) {
            this.autodetectInterfaces = autodetectInterfaces;
        }

        /**
         * 设置是否单件模式
         */
        public void setSingleton(boolean singleton) {
            this.singleton = singleton;
        }

        /**
         *you know。。。
         */
        public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
            this.advisorAdapterRegistry = advisorAdapterRegistry;
        }

        @Override
        public void setFrozen(boolean frozen) {
            this.freezeProxy = frozen;
        }

        public void setProxyClassLoader(ClassLoader classLoader) {
            this.proxyClassLoader = classLoader;
            this.classLoaderConfigured = (classLoader != null);
        }

        public void setBeanClassLoader(ClassLoader classLoader) {
            if (!this.classLoaderConfigured) {
                this.proxyClassLoader = classLoader;
            }
        }
      //拥有了beanfacotry的能力了。
        public void setBeanFactory(BeanFactory beanFactory) {
            this.beanFactory = beanFactory;
            checkInterceptorNames();
        }

        /**
         * 对象获取的输入,深入分析此处!!!
         */
        public Object getObject() throws BeansException {
            initializeAdvisorChain(); //第一次获取会初始化注册的advice 并进行包装 为Advisor
            if (isSingleton()) {
                return getSingletonInstance(); //如果是单例,返回代理对象
            }
            else {
                if (this.targetName == null) {
                    logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
                            "Enable prototype proxies by setting the 'targetName' property.");
                }
                return newPrototypeInstance(); //多例的情况
            }
        }

        public Class<?> getObjectType() {
            synchronized (this) {
                if (this.singletonInstance != null) {
                    return this.singletonInstance.getClass();
                }
            }
            Class[] ifcs = getProxiedInterfaces();
            if (ifcs.length == 1) {
                return ifcs[0];
            }
            else if (ifcs.length > 1) {
                return createCompositeInterface(ifcs);
            }
            else if (this.targetName != null && this.beanFactory != null) {
                return this.beanFactory.getType(this.targetName);
            }
            else {
                return getTargetClass();
            }
        }

        public boolean isSingleton() {
            return this.singleton;
        }

        /**
         *根据提供的接口列表,组装一个综合接口,实现所有的参数接口
         */
        protected Class createCompositeInterface(Class[] interfaces) {
            return ClassUtils.createCompositeInterface(interfaces, this.proxyClassLoader);
        }

        /**
         * 返回单例的代理对象
         */
        private synchronized Object getSingletonInstance() {
            if (this.singletonInstance == null) { //如果第一次调用
                this.targetSource = freshTargetSource();
                if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
                    // Rely on AOP infrastructure to tell us what interfaces to proxy.
                    Class targetClass = getTargetClass();
                    if (targetClass == null) {
                        throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
                    }
                    setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
                }
                // Initialize the shared singleton instance.
                super.setFrozen(this.freezeProxy);
                this.singletonInstance = getProxy(createAopProxy()); //创建单例 createAopProxy 里使用 AopProxyFactory 根据当前配置创建aop代理(这块的细节参考ProxyFactory的讲解)
            }
            return this.singletonInstance;
        }

          //返回一个新的代理对象
        private synchronized Object newPrototypeInstance() {
            if (logger.isTraceEnabled()) {
                logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
            }

        // copy 一份当前ProxyFacotryBean的配置 getAopProxyFactory 返回的工厂是可以复用的,他没有状态
            ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
            // The copy needs a fresh advisor chain, and a fresh TargetSource.
            TargetSource targetSource = freshTargetSource();
            copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain()); //浅copy
            if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
                // Rely on AOP infrastructure to tell us what interfaces to proxy.
                copy.setInterfaces(
                        ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
            }
            copy.setFrozen(this.freezeProxy);

            if (logger.isTraceEnabled()) {
                logger.trace("Using ProxyCreatorSupport copy: " + copy);
            }
            return getProxy(copy.createAopProxy());
        }

        /**
         * 返回一个代理对象 AopProxy 有jdk 和cglib两种实现
         */
        protected Object getProxy(AopProxy aopProxy) {
            return aopProxy.getProxy(this.proxyClassLoader);
        }

        /**
         * 检查处理interceptorNames 最后一个配置 是否是advice 或者advisor ,否则设置为target
         */
        private void checkInterceptorNames() {
            if (!ObjectUtils.isEmpty(this.interceptorNames)) {
                String finalName = this.interceptorNames[this.interceptorNames.length - 1];
                if (this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
                    //如果最后一个对象是设置的tareget实例
                    if (!finalName.endsWith(GLOBAL_SUFFIX) && !isNamedBeanAnAdvisorOrAdvice(finalName)) {
                        // finalName 不是拦截器
                        this.targetName = finalName;
                        if (logger.isDebugEnabled()) {
                            logger.debug("Bean with name '" + finalName + "' concluding interceptor chain " +
                                    "is not an advisor class: treating it as a target or TargetSource");
                        }
                        String[] newNames = new String[this.interceptorNames.length - 1];
                        System.arraycopy(this.interceptorNames, 0, newNames, 0, newNames.length);
                        this.interceptorNames = newNames;
                    }
                }
            }
        }

        /**
         * 判断是否是Advisor 或者Advice
         */
        private boolean isNamedBeanAnAdvisorOrAdvice(String beanName) {
            Class namedBeanClass = this.beanFactory.getType(beanName);
            if (namedBeanClass != null) {
                return (Advisor.class.isAssignableFrom(namedBeanClass) || Advice.class.isAssignableFrom(namedBeanClass));
            }
            // Treat it as an target bean if we can't tell.
            if (logger.isDebugEnabled()) {
                logger.debug("Could not determine type of bean with name '" + beanName +
                        "' - assuming it is neither an Advisor nor an Advice");
            }
            return false;
        }

        private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
            if (this.advisorChainInitialized) {
                return;
            }

            if (!ObjectUtils.isEmpty(this.interceptorNames)) {
                if (this.beanFactory == null) {
                    throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
                            "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
                }

                // 如果指定了全局拦截器,那么必须显示指定targetSource 或者targetName
                if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
                        this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
                    throw new AopConfigException("Target required after globals");
                }

                for (String name : this.interceptorNames) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Configuring advisor or advice '" + name + "'");
                    }

                    if (name.endsWith(GLOBAL_SUFFIX)) { //如果匹配后缀*
                        if (!(this.beanFactory instanceof ListableBeanFactory)) {
                            throw new AopConfigException(
                                    "Can only use global advisors or interceptors with a ListableBeanFactory");
                        }
                        addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
                                name.substring(0, name.length() - GLOBAL_SUFFIX.length())); //添加通配的advisor
                    }

                    else {
                        // 
                        Object advice;
                        if (this.singleton || this.beanFactory.isSingleton(name)) {
                            // 如果是单例,直接添加 Advisor/Advice to the chain.
                            advice = this.beanFactory.getBean(name); 
                        }
                        else {
                            //生成一个占位的advisor
                            advice = new PrototypePlaceholderAdvisor(name);
                        }
                        addAdvisorOnChainCreation(advice, name);
                    }
                }
            }

            this.advisorChainInitialized = true;
        }

        /**
         * 返回独立的 advisor 列表,每次创建prototype 实例的时候,都要
         */
        private List<Advisor> freshAdvisorChain() {
            Advisor[] advisors = getAdvisors();
            List<Advisor> freshAdvisors = new ArrayList<Advisor>(advisors.length);
            for (Advisor advisor : advisors) {
                if (advisor instanceof PrototypePlaceholderAdvisor) { //如果是占位advisor实例
                    PrototypePlaceholderAdvisor pa = (PrototypePlaceholderAdvisor) advisor;
                    if (logger.isDebugEnabled()) {
                        logger.debug("Refreshing bean named '" + pa.getBeanName() + "'");
                    }
                    if (this.beanFactory == null) {
                        throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
                                "- cannot resolve prototype advisor '" + pa.getBeanName() + "'");
                    }
                    Object bean = this.beanFactory.getBean(pa.getBeanName());
                    Advisor refreshedAdvisor = namedBeanToAdvisor(bean);
                    freshAdvisors.add(refreshedAdvisor);
                }
                else {
                    // Add the shared instance.
                    freshAdvisors.add(advisor);
                }
            }
            return freshAdvisors;
        }

        /**
          增加全局的通知器
         */
        private void addGlobalAdvisor(ListableBeanFactory beanFactory, String prefix) {
            String[] globalAdvisorNames =
                    BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Advisor.class); //找到所有Advisor
            String[] globalInterceptorNames =
                    BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Interceptor.class); //找到所有Interceptor
            List<Object> beans = new ArrayList<Object>(globalAdvisorNames.length + globalInterceptorNames.length);
            Map<Object, String> names = new HashMap<Object, String>(beans.size());
            for (String name : globalAdvisorNames) {
                Object bean = beanFactory.getBean(name);
                beans.add(bean);
                names.put(bean, name);
            }
            for (String name : globalInterceptorNames) {
                Object bean = beanFactory.getBean(name);
                beans.add(bean);
                names.put(bean, name);
            }
            OrderComparator.sort(beans); 
            for (Object bean : beans) {
                String name = names.get(bean);
                if (name.startsWith(prefix)) {
                    addAdvisorOnChainCreation(bean, name);
                }
            }
        }

        /**
         * 当advice 创建的时候,增加Advice到拦截器列表
         */
        private void addAdvisorOnChainCreation(Object next, String name) {
            Advisor advisor = namedBeanToAdvisor(next);
            if (logger.isTraceEnabled()) {
                logger.trace("Adding advisor with name '" + name + "'");
            }           
            addAdvisor(advisor);
        }

        private TargetSource freshTargetSource() {
            if (this.targetName == null) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Not refreshing target: Bean name not specified in 'interceptorNames'.");
                }
                return this.targetSource;
            }
            else {
                if (this.beanFactory == null) {
                    throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
                            "- cannot resolve target with name '" + this.targetName + "'");
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Refreshing target with name '" + this.targetName + "'");
                }
                Object target = this.beanFactory.getBean(this.targetName);
                return (target instanceof TargetSource ? (TargetSource) target : new SingletonTargetSource(target));
            }
        }

        /**
         * Advisor or Advice转换为 Advisor
         */
        private Advisor namedBeanToAdvisor(Object next) {
            try {
                return this.advisorAdapterRegistry.wrap(next);
            }
            catch (UnknownAdviceTypeException ex) {
                throw new AopConfigException("Unknown advisor type " + next.getClass() +
                        "; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
                        "which may also be target or TargetSource", ex);
            }
        }

        @Override
        protected void adviceChanged() {
            super.adviceChanged();
            if (this.singleton) {
                logger.debug("Advice has changed; recaching singleton instance");
                synchronized (this) {
                    this.singletonInstance = null;
                }
            }
        }

        private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
            // Rely on default serialization; just initialize state after deserialization.
            ois.defaultReadObject();

            // Initialize transient fields.
            this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
        }

        /**
         * Used in the interceptor chain where we need to replace a bean with a prototype
         * on creating a proxy.
         */
        private static class PrototypePlaceholderAdvisor implements Advisor, Serializable {

            private final String beanName;

            private final String message;

            public PrototypePlaceholderAdvisor(String beanName) {
                this.beanName = beanName;
                this.message = "Placeholder for prototype Advisor/Advice with bean name '" + beanName + "'";
            }

            public String getBeanName() {
                return beanName;
            }

            public Advice getAdvice() {
                throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
            }

            public boolean isPerInstance() {
                throw new UnsupportedOperationException("Cannot invoke methods: " + this.message);
            }

            @Override
            public String toString() {
                return this.message;
            }
        }

    }

来源:http://ddrv.cn

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring-aop-ProxyFactoryBean 源码分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏