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

回到顶部