AspectJ切点指示器05this
1、Factory
package com.test.aspectj.expression;/**
* 工厂接口
*/
public interface Factory {
// 制作产品
void make();
// 运输
void delivery(String address);
}
2、PhoneFactory
package com.test.aspectj.expression;import com.test.aspectj.expression.args.FreshFoodFactory;
import com.test.aspectj.expression.args.FrozenFoodFactory;
import org.springframework.stereotype.Component;
/**
* 食品工厂
*/
@Component
public class FoodFactory implements Factory {
// 制作产品的方法
@Override
public void make() {
System.out.println("来自目标类FoodFactory的消息:生产食品");
}
// 运输
@Override
public void delivery(String address) {
System.out.println("来自目标类FoodFactory的消息:销售食品至 " + address);
}
// 能匹配到 @args(com.test.aspectj.expression.args.Listen) 切入点
public void testArgsAnnotation(FreshFoodFactory freshFoodFactory) {
}
// 不能匹配到 @args(com.test.aspectj.expression.args.Listen) 切入点
public void testFrozenArgsAnnotation(FrozenFoodFactory frozenFoodFactory) {
}
}
3、引介切面要实现的接口 Listener
package com.test.aspectj.expression.thisexpression;/**
* 引介切面要实现的接口
*/
public interface Listener {
/**
* 监听
*/
void listen();
}
4、Listener接口实现类
package com.test.aspectj.expression.thisexpression;/**
* Listener接口实现类
*/
public class DefaultListener implements Listener {
/**
* 监听
*/
@Override
public void listen() {
System.out.println("来自DefaultListener的消息:开始监听");
}
}
5、定义引介切面ListenerAspect,其为FoodFactory植入Listener接口
package com.test.aspectj.expression.thisexpression;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.core.Ordered;
/**
* 为FoodFactory添加Listener接口的切面
*/
@Aspect
public class ListenerAspect implements Ordered {
/**
* 为FoodFactory添加接口实现,要实现的接口是Listener,接口的默认实现是DefaultListener
*/
@DeclareParents(value = "com.test.aspectj.expression.FoodFactory", defaultImpl = DefaultListener.class)
public static Listener listener;
/**
* 如果有多个切面,注意多切面织入的顺序
*/
@Override
public int getOrder() {
return 2;
}
}
6、测试this和target的切面
package com.test.aspectj.expression.thisexpression;import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.Ordered;
import javax.annotation.Resource;
/**
* 测试this和target的切面
*/
@Aspect
public class ThisAspect implements Ordered {
/**
* 织入运行期对象为Listener类型的Bean中
*
* 不仅可以匹配Listener接口中定义的方法,而且还可以匹配FoodFactory中的方法
*/
@AfterReturning("this(com.test.aspectj.expression.thisexpression.Listener)")
public void after() {
System.out.println("来自切面里的消息:ThisAspect after方法执行了");
}
/**
* 仅仅匹配Listener中定义的方法
*/
@Before("target(com.test.aspectj.expression.thisexpression.Listener)")
public void before() {
System.out.println("来自切面里的消息:ThisAspect before方法执行了");
}
/**
* 如果有多个切面,注意多切面织入的顺序
*/
@Override
public int getOrder() {
return 1;
}
}
7、xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.test.aspectj.expression"/>
<bean id="listenerAspect" class="com.test.aspectj.expression.thisexpression.ListenerAspect"/>
<bean id="thisAspect" class="com.test.aspectj.expression.thisexpression.ThisAspect"/>
<aop:aspectj-autoproxy />
</beans>
8、测试代码
package com.test.aspectj.expression.thisexpression;import com.test.aspectj.expression.FoodFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试
*/
public class ThisExpressionDemo {
public static void main(String[] args) {
System.out.println("=============== 测试 this ===============");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-chapter3-aspectjthisexpression.xml");
FoodFactory foodFactory = (FoodFactory) context.getBean("foodFactory");
foodFactory.make();
System.out.println("-----分割线-----");
Listener listener = (Listener) foodFactory;
listener.listen();
}
}
9、理论上运行结果如下
=============== 测试 this ===============来自目标类FoodFactory的消息:生产食品
来自切面里的消息:ThisAspect after方法执行了
-----分割线-----
来自切面里的消息:ThisAspect before方法执行了
来自DefaultListener的消息:开始监听
来自切面里的消息:ThisAspect after方法执行了
但是在测试过程报错如下(还需要验证结论的正确性)
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy16 cannot be cast to com.test.aspectj.expression.FoodFactory at com.test.aspectj.expression.thisexpression.ThisExpressionDemo.main(ThisExpressionDemo.java:14)
10、总结
- this(com.test.aspectj.expression.thisexpression.Listener)不仅可以匹配Listener接口中定义的方法,而且还可以匹配FoodFactory中的方法;
- target(com.test.aspectj.expression.thisexpression.Listener)仅仅匹配Listener中定义的方法。
以上是 AspectJ切点指示器05this 的全部内容, 来源链接: utcz.com/z/513087.html