您的位置:首页 > 编程语言 > Java开发

SpringAOP类型代理

2017-01-06 23:11 411 查看
spring本身提供的是通过匹配bean的名称来拦截的方法,
通过类型能够准确的拦截,避免了用户命名造成的多余拦截甚至造成系统异常.

参考了druid的方法

com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator

org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator

核心方法如下

import java.util.Arrays;
import java.util.List;

import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.PatternMatchUtils;

public class BeanTypeAutoProxyCreator extends AbstractAutoProxyCreator
implements InitializingBean, ApplicationContextAware {

/**
*
*/
private static final long serialVersionUID = 1L;

private ApplicationContext applicationContext;

private Class<?> beanType;

private Class<?> adviceType;

private List<String> beanNames;

@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}

@Override
public void afterPropertiesSet() throws Exception {
beanNames = Arrays.asList(this.applicationContext
.getBeanNamesForType(beanType));
super.setInterceptorNames(this.applicationContext
.getBeanNamesForType(adviceType));
}

protected boolean isMatch(String beanName, String mappedName) {
return PatternMatchUtils.simpleMatch(mappedName, beanName);
}

@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass,
String beanName, TargetSource customTargetSource)
throws BeansException {
if (this.beanNames != null) {
for (String mappedName : this.beanNames) {
if (FactoryBean.class.isAssignableFrom(beanClass)) {
if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
continue;
}
mappedName = mappedName
.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
if (isMatch(beanName, mappedName)) {
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
BeanFactory beanFactory = getBeanFactory();
if (beanFactory != null) {
String[] aliases = beanFactory.getAliases(beanName);
for (String alias : aliases) {
if (isMatch(alias, mappedName)) {
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
}
}
}
}
return DO_NOT_PROXY;
}

public void setBeanType(Class<?> beanType) {
this.beanType = beanType;
}

public void setAdviceType(Class<?> adviceType) {
this.adviceType = adviceType;
}

<bean class="rml.proxy.BeanTypeAutoProxyCreator">
<property name="beanType" value="rml.proxy.AbstractByProxy">
</property>
<property name="adviceType" value="rml.proxy.MyAdvice">
</property>
</bean>

public abstract class AbstractByProxy {

abstract void doSomething(String ars);
}

public interface MyAdvice {

}

这样我们就可以只实现了AbstractByProxy的类代理实现MyAdvice接口

从而达到限制类型的目的

@Log4j
@Component
public class AByProxy extends AbstractByProxy {

@Override
public void doSomething(String ars) {
log.error("AByProxy.............");
}

}

@Log4j
@Component
public class TestAdvice implements MethodBeforeAdvice,MyAdvice{

@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
if(method.getName().equals("doSomething")){
log.error(Arrays.asList(args));
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring aop proxy advice