Spring 动态注入代理(AOP)\手动注入new出来的Bean

1,374 阅读1分钟

注意 AOP 组件需要比被代理的Bean先注入到容器中,否则不生效。我使用的是 BeanDefinitionRegistryPostProcessor 方式实现,在 Bean 未生成前将AOP组件注入到容器中。如果还有其它的方式请告知,谢谢啦。

package customercenter.config;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;
import java.util.function.Supplier;

@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DynamicProxyConfiguration implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

    }

	/**
	* 主要逻辑
	*/
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        for (String beanName : beanFactory.getBeanNamesForType(ProxyMsgSupplier.class)) {
            ProxyMsgSupplier getProxyMsg = (ProxyMsgSupplier) beanFactory.getBean(beanName);
            for (ProxyMsg proxyMsg : getProxyMsg.get()) {
                Pointcut staticMethodMatcherPointcut =
                        getStaticMethodMatcherPointcut(proxyMsg);
                beanFactory.registerSingleton(proxyMsg.getClassMsg() + "staticMethodMatcherPointcut", staticMethodMatcherPointcut);

                Advisor advisor = getTestStaticMethodMatcherPointcut(
                        staticMethodMatcherPointcut,
                        proxyMsg.getMethodInterceptor()
                );

                beanFactory.registerSingleton(proxyMsg.getClassMsg() + "TestStaticMethodMatcherPointcut", advisor);
            }
        }
    }

    public static Pointcut getStaticMethodMatcherPointcut(DynamicProxyConfiguration.ProxyMsg proxyMsg) {
        return new StaticMethodMatcherPointcut() {
            @Override
            public boolean matches(Method method, Class<?> targetClass) {
                return targetClass.getName().equals(proxyMsg.getClassMsg()) &&
                        method.getName().equals(proxyMsg.getPoint());
            }
        };
    }

    public static Advisor getTestStaticMethodMatcherPointcut(Pointcut staticMethodMatcherPointcut,
                                                             MethodInterceptor methodInterceptor) {
        DefaultBeanFactoryPointcutAdvisor defaultBeanFactoryPointcutAdvisor = new DefaultBeanFactoryPointcutAdvisor();
        defaultBeanFactoryPointcutAdvisor.setPointcut(staticMethodMatcherPointcut);
        defaultBeanFactoryPointcutAdvisor.setAdvice(methodInterceptor);
        return defaultBeanFactoryPointcutAdvisor;
    }

    public interface ProxyMsgSupplier extends Supplier<List<? extends ProxyMsg>> {

    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class ProxyMsg {
        private String classMsg;
        private String point;
        private MethodInterceptor methodInterceptor;
    }
}

/*
* 获取代理逻辑和代理信息
*/
@Component
public class ClassMsgList implements DynamicProxyConfiguration.ProxyMsgSupplier {

    @Override
    public MethodInterceptor getMethodInterceptor(TbIntegralModel tbIntegralModel) {
        return new MethodInterceptor() {
            public Object invoke(MethodInvocation methodInvocation) throws Throwable {
                System.out.println("方法运行前");
                return null;
            }
        };
    }

    @Override
    public List<DynamicProxyConfiguration.ProxyMsg> get() {
        List<DynamicProxyConfiguration.ProxyMsg> result = new ArrayList<>(5);
                result.add(new DynamicProxyConfiguration.ProxyMsg("className", "methodName", getMethodInterceptor(tbIntegralModel)));
        return result;
    }
}