1.结构
2.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cskaoyan</groupId>
<artifactId>demo2-pointcut</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>6</source>
<target>6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency><dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
3.advice(通知器)
CountTimeAdvice(用于时间增强,添加时间属性)
@Component
public class CountTimeAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
long start = System.currentTimeMillis();
Object proceed = methodInvocation.proceed();
long end = System.currentTimeMillis();
System.out.println(methodInvocation.getMethod().getName() + "方法执行时间为:" + (end - start));
return proceed;
}
}
CustomAdvice(测试委托类执行前后的输出)
proceed的源代码
JoinPoint连接点:代理对象正在执行的方法
@Component
public class CustomAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("正道的光");
Object proceed = methodInvocation.proceed();
System.out.println("照在了大地上");
return proceed;
}
}
4.anno(注解)
CountTime
@Target(ElementType.METHOD) //注解写在哪里 👉 方法上
@Retention(RetentionPolicy.RUNTIME) //运行时生效
public @interface CountTime {
}
5.bean
public class User {
}
6.service(service层组件)
OrderService
public interface OrderService {
public void method1();
public void method2();
public void method3();
}
OrderServiceImpl
@Service
public class OrderServiceImpl implements OrderService{
@CountTime
@Override
public void method1() {
System.out.println("method1");
}
@Override
public void method2() {
System.out.println("method2");
}
@CountTime
@Override
public void method3() {
System.out.println("method3");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
UserService
public interface UserService {
public void sayHello();
public String sayHello2(String name);
public User sayHello3(String name);
}
UserServiceImpl
@Service
public class UserServiceImpl implements UserService{
@Override
public void sayHello() {
System.out.println("hello world");
}
@Override
public String sayHello2(String name) {
String result = "hello " + name;
System.out.println(result);
return result;
}
@Override
public User sayHello3(String name) {
System.out.println("sayHello3");
return null;
}
}
7.spring配置
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- bean definitions here -->
<context:component-scan base-package="com.cskaoyan"/>
<!--aop:pointcut-->
<aop:config>
<!--切入点表达式:判断方法是否在切入点表达式范围内-->
<!--
修饰符:可以省略 👉 省略不写代表任意修饰符
返回值:不能省略;可以使用*来通配;如果返回值为pojo,需要写全类名
包名、类名、方法名:
可以部分省略 👉 除了头和尾,中间的任意一部分都可以使用..来进行省略
可以通配 👉 *来通配一整个词或词的一部分
形参:
可以省略 👉 无参方法
特殊用法 👉 和返回值一样,pojo类要写全类名
能否通配 👉 * 代表的单个任意参数;
.. 任意数量任意类型的参数
-->
<aop:pointcut id="mypointcut1" expression="execution(public * com.cskaoyan.service..sayHello*(String,com.cskaoyan.bean.User))"/>
<aop:pointcut id="mypointcut2" expression="execution(public * com.cskaoyan.service..*(*,*))"/>
<aop:pointcut id="mypointcut3" expression="execution(public * com.cskaoyan.service..*(*,*))"/>
<!--service层里任意以sayHello开头的方法-->
<aop:pointcut id="mypointcut4" expression="execution(* com.cskaoyan.service..sayHello*(..))"/>
<!--<aop:pointcut id="mypointcut4" expression="execution(* com.cskaoyan.service..sayHello())"/>-->
<aop:pointcut id="countTimePointcut" expression="@annotation(com.cskaoyan.anno.CountTime)"/>
<aop:advisor advice-ref="customAdvice" pointcut-ref="mypointcut4"/>
<aop:advisor advice-ref="countTimeAdvice" pointcut-ref="countTimePointcut"/>
</aop:config>
</beans>
8.测试类
MyTest
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class MyTest {
@Autowired
UserService userService;
@Test
public void mytest(){
userService.sayHello();
}
@Test
public void mytest2(){
userService.sayHello2("远志");
}
@Test
public void mytest3(){
userService.sayHello3("景甜");
}
}
结果:
MyTest2
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class MyTest2 {
@Autowired
OrderService orderService;
@Test
public void mytest(){
orderService.method1();
}
@Test
public void mytest2(){
orderService.method2();
}
@Test
public void mytest3(){
orderService.method3();
}
}
结果: