??? profile是Spring3.1提供的一个新的配置项,在下面的测试示例中,又有使用了多种AOP配置方式,为了将各种配置方式进行对比在此使用了profile.在测试用例中通过使用@ActiveProfiles("four")注解指定profile的值。
? Aop?是Spring?框架的核心功能之一。
??? Advice?通知时定义在该连接点做什么,为切面增强提供织入接口。Advice是AOP联盟定义的一个接口,在Spring中对其进行了扩展,提供了更为具体的接口如:BeforeAdvice,AfterAdvice,ThrwosAdvice等。
?
public interface MethodBeforeAdvice extends BeforeAdvice {
/**
*在指定方法调用前执行该回调方法
*/
void before(Method method, Object[] args, Object target) throws Throwable;
}
?Pointcut切点,决定advice通知应该作用于哪个连接点,也就是说Pointcut来定义需要增强方法的集合,这些集合的选取可以按照一定的规则来完成。Spring中默认提供了JdkRegexpMethodPointcut,基于正则表达式去匹配增强方法。
???Advisor通知器,在完成对既定目标的增强切面的设计(advice)和关注点的设计(Pointcut)以后,还需要将Advice和Pointcut两者关联起来,完成这个工作的就是Advisor.?通过Advisor,可以定义在哪个关注点上使用哪个通知。在Spring?中默认提供了一个DefultPointcutAdvisor,并以此为例完成AOP demo.
public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable {
private Pointcut pointcut = Pointcut.TRUE;
public DefaultPointcutAdvisor() {
}
public DefaultPointcutAdvisor(Advice advice) {
this(Pointcut.TRUE, advice);
}
public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {
this.pointcut = pointcut;
setAdvice(advice);
}
//设置切点
public void setPointcut(Pointcut pointcut) {
this.pointcut = (pointcut != null ? pointcut : Pointcut.TRUE);
}
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public String toString() {
return getClass().getName() + ": pointcut [" + getPointcut() + "]; advice [" + getAdvice() + "]";
}
}
public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable {
//优先级
private Integer order;
public void setOrder(int order) {
this.order = order;
}
public int getOrder() {
if (this.order != null) {
return this.order;
}
Advice advice = getAdvice();
if (advice instanceof Ordered) {
return ((Ordered) advice).getOrder();
}
return Ordered.LOWEST_PRECEDENCE;
}
public boolean isPerInstance() {
return true;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof PointcutAdvisor)) {
return false;
}
PointcutAdvisor otherAdvisor = (PointcutAdvisor) other;
return (ObjectUtils.nullSafeEquals(getAdvice(), otherAdvisor.getAdvice()) &&
ObjectUtils.nullSafeEquals(getPointcut(), otherAdvisor.getPointcut()));
}
@Override
public int hashCode() {
return PointcutAdvisor.class.hashCode();
}
}
public abstract class AbstractGenericPointcutAdvisor extends AbstractPointcutAdvisor {
private Advice advice;
public void setAdvice(Advice advice) {
this.advice = advice;
}
public Advice getAdvice() {
return this.advice;
}
@Override
public String toString() {
return getClass().getName() + ": advice [" + getAdvice() + "]";
}
}
?在Spring AOP?使用中可以通过ProxyFactoryBean来配置目标对象和切面的行为。在ProxyFactoryBean中通过interceptorNames属性来配置已经定义好的advisor.虽然名字是interceptor实际上就是配置advisor.在ProxyFactoryBean中需要为target目标对象生成一个动态代理对象proxy,从而为AOP切面的编织做好准备工作。
?
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
/**
* This suffix in a value in an interceptor list indicates to expand globals.
*/
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;
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
private boolean freezeProxy = false;
private transient ClassLoader proxyClassLoader = ClassUtils.getDefaultClassLoader();
private transient boolean classLoaderConfigured = false;
private transient BeanFactory beanFactory;
/** Whether the advisor chain has already been initialized */
private boolean advisorChainInitialized = false;
/** If this is a singleton, the cached singleton proxy instance */
private Object singletonInstance;
public void setProxyInterfaces(Class[] proxyInterfaces) throws ClassNotFoundException {
setInterfaces(proxyInterfaces);
}
public void setInterceptorNames(String[] interceptorNames) {
this.interceptorNames = interceptorNames;
}
public void setTargetName(String targetName) {
this.targetName = targetName;
}
public void setAutodetectInterfaces(boolean autodetectInterfaces) {
this.autodetectInterfaces = autodetectInterfaces;
}
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
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;
}
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
checkInterceptorNames();
}
/**
* 返回一个代理对象。当客户端从这个FactoryBean中获取bean时调用该接口
*/
public Object getObject() throws BeansException {
//初始化通知器链
initializeAdvisorChain();
//如果是单例的则返回一个单例实例
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.");
}
//返回以prototype实例
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()) {
// 根据AOP框架来判断需要代理的接口
Class targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
//设置代理接口
setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// 初始化一个单例
super.setFrozen(this.freezeProxy);
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
/**
* 创建一个新的prototype 代理对象
*/
private synchronized Object newPrototypeInstance() {
if (logger.isTraceEnabled()) {
logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
}
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
TargetSource targetSource = freshTargetSource();
copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
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());
}
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
/**
* 检查interceptorNames列表中最后一个元素是否是目标对象名称。
*/
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) {
// The last name in the chain may be an Advisor/Advice or a target/TargetSource.
// Unfortunately we don‘t know; we must look at type of the bean.
if (!finalName.endsWith(GLOBAL_SUFFIX) && !isNamedBeanAnAdvisorOrAdvice(finalName)) {
// The target isn‘t an interceptor.
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;
}
}
}
}
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则最后一个通知器不能是全局通知器
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 + "‘");
}
//如果通知器名称是以*结尾的且beanFactory不适ListableBeanFactory则抛出异常,否则添加全局通知器
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()));
}
else {
//非全局通知器
Object advice;
//如果该beanFactory是单例的或者是通知器是单例的则从beanFactory中获取单例的通知器,否则获取一个原型的通知器
if (this.singleton || this.beanFactory.isSingleton(name)) {
advice = this.beanFactory.getBean(name);
}
else {
advice = new PrototypePlaceholderAdvisor(name);
}
//添加到通知器链中
addAdvisorOnChainCreation(advice, name);
}
}
}
//设置通知器初始化完成标识
this.advisorChainInitialized = true;
}
/**
* 返回通知器列表
*/
private List<Advisor> freshAdvisorChain() {
Advisor[] advisors = getAdvisors();
List<Advisor> freshAdvisors = new ArrayList<Advisor>(advisors.length);
for (Advisor advisor : advisors) {
if (advisor instanceof PrototypePlaceholderAdvisor) {
PrototypePlaceholderAdvisor pa = (PrototypePlaceholderAdvisor) advisor;
if (logger.isDebugEnabled()) {
logger.debug("Refreshing bean named ‘" + pa.getBeanName() + "‘");
}
// Replace the placeholder with a fresh prototype instance resulting
// from a getBean() lookup
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) {
//获取beanFactory中定义的所有的通知器
String[] globalAdvisorNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Advisor.class);
// 获取beanFactory中定义的所有的Interceptor
String[] globalInterceptorNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Interceptor.class);
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);
}
}
}
/**
* 添加一个通知器
*/
private void addAdvisorOnChainCreation(Object next, String name) {
//转换为一个通知器
Advisor advisor = namedBeanToAdvisor(next);
if (logger.isTraceEnabled()) {
logger.trace("Adding advisor with name ‘" + name + "‘");
}
//添加通知器
addAdvisor(advisor);
}
/**
* 在创建一个代理对象时返回一个TargetSource
*/
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));
}
}
/**
* 对给定的对象转换为一个通知器
*/
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();
}
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;
}
}
}
?ProxyCreatorSupport
?
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
?DefaultAopProxyFactory,这里是实际创建代理的地方
?
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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.");
}
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
if (!cglibAvailable) {
throw new AopConfigException(
"Cannot proxy target class because CGLIB2 is not available. " +
"Add CGLIB to the class path or specify proxy interfaces.");
}
return CglibProxyFactory.createCglibProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
?
?
?
?
?
?
?
?
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
"
default-autowire="byType">
<!-- 定义一个通知 -->
<bean id="authInterceptor" class="com.cathy.demo.spring.aop.AuthInterceptor" />
<!-- 定义切点,匹配所有方法 -->
<bean id="authPoint" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*" />
</bean>
<!-- 定义通知 器 -->
<bean id="authAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut" ref="authPoint" />
<property name="advice" ref="authInterceptor" />
</bean>
<bean id="aopDemo" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="com.cathy.demo.spring.aop.AopDemo" />
</property>
<property name="interceptorNames" value="authAdvisor" />
<property name="proxyInterfaces" value="com.cathy.demo.spring.aop.Say" />
</bean>
</beans>
?
/**
* 方法调用前的权限拦截器
* @author zhangwei_david
* @version $Id: AuthInterceptor.java, v 0.1 2015年7月10日 上午10:18:12 zhangwei_david Exp $
*/
public class AuthInterceptor implements MethodBeforeAdvice {
/**
* @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
*/
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("调用 方法:" + method);
}
}
?
/**
*
* @author zhangwei_david
* @version $Id: AopDemo.java, v 0.1 2015年7月10日 上午10:21:20 zhangwei_david Exp $
*/
public class AopDemo implements Say {
public void say() {
System.out.println("hello");
}
}
?
/**
*
*
* @author zhangwei_david
* @version $Id: SpringAopTest.java, v 0.1 2015年7月10日 上午10:51:16 zhangwei_david Exp $
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:META-INF/spring/aop-beans.xml")
public class SpringAopTest {
@Autowired
private Say aopDemo;
@Test
public void test() {
aopDemo.say();
}
}
?
2015-07-10 10:40:14 [ main:375 ] - [ INFO ] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@190a65e: defining beans [authInterceptor,authPoint,authAdvisor,aopDemo,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy 调用 方法:public abstract void com.cathy.demo.spring.aop.Say.say() hello 2015-07-10 10:40:14 [ Thread-0:494 ] - [ INFO ] Closing org.springframework.context.support.GenericApplicationContext@ee68d8: startup date [Fri Jul 10 10:40:14 CST 2015]; root of context hierarchy 2015-07-10 10:40:14 [ Thread-0:494 ] - [ INFO ] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@190a65e: defining beans [authInterceptor,authPoint,authAdvisor,aopDemo,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
?
其他的配置方式如下:
/**
* 方法调用前的权限拦截器
* @author zhangwei_david
* @version $Id: AuthInterceptor.java, v 0.1 2015年7月10日 上午10:18:12 zhangwei_david Exp $
*/
@Component
@Aspect
public class BeforeInterceptor {
@Before("execution(* *.*(..))")
public void before(JoinPoint joinPoint) throws Throwable {
System.out.println("before [target" + joinPoint.getTarget() + ", signature:"
+ joinPoint.getSignature());
}
}
?
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
"
default-autowire="byType">
<!-- 使用ProxyFactoryBean 实现aop -->
<beans profile="one">
<!-- 定义一个通知 -->
<bean id="authInterceptor" class="com.cathy.demo.spring.aop.AuthInterceptor" />
<!-- 定义切点,匹配所有方法 -->
<bean id="authPoint"
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*" />
</bean>
<!-- 定义通知 器 -->
<bean id="authAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut" ref="authPoint" />
<property name="advice" ref="authInterceptor" />
</bean>
<bean id="aopDemo" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="com.cathy.demo.spring.aop.AopDemo" />
</property>
<property name="interceptorNames" value="auth*" />
</bean>
</beans>
<!-- 优化配置,使用DefaultAdvisorAutoProxyCreator -->
<beans profile="two">
<!-- 定义一个通知 -->
<bean id="authInterceptor" class="com.cathy.demo.spring.aop.AuthInterceptor" />
<!-- 定义通知 器 -->
<bean id="authAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="pattern" value=".*" />
<property name="advice" ref="authInterceptor" />
</bean>
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
p:usePrefix="true" p:advisorBeanNamePrefix="auth" />
<bean id="aopDemo" class="com.cathy.demo.spring.aop.AopDemo" />
</beans>
<!-- 使用aop命名空间进行配置 -->
<beans profile="three">
<bean id="authInterceptor" class="com.cathy.demo.spring.aop.BeforeInterceptor" />
<bean id="aopDemo" class="com.cathy.demo.spring.aop.AopDemo" />
<aop:config>
<aop:aspect ref="authInterceptor">
<aop:before method="before" pointcut="execution(* *.*(..))" />
</aop:aspect>
</aop:config>
</beans>
<!-- 自动扫描 @Aspectj -->
<beans profile="four">
<aop:aspectj-autoproxy />
<context:annotation-config />
<context:component-scan base-package="com.cathy.demo.spring.*" />
</beans>
</beans>
?
/**
*
*
* @author zhangwei_david
* @version $Id: SpringAopTest.java, v 0.1 2015年7月10日 上午10:51:16 zhangwei_david Exp $
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath*:META-INF/spring/aop-beans.xml")
@ActiveProfiles("four")
public class SpringAopFourTest {
@Autowired
private Say aopDemo;
@Test
public void test() {
aopDemo.say();
}
}
?
原文:http://zhangwei-david.iteye.com/blog/2226203