spring aop基于代理实现,主要包含两种----接口代理,类代理
接口代理 可参考jdk代理,主要通过反射来实现
类代理 可参考cglib代理,主要使用继承来实现
注:两种代理均无法实现对私有方法和静态方法的代理
这两种代理都可以看做代理设计模式的一种实现.
前一段时间要统计一个项目中各个方法的执行时间,就用spring aop做了一个实现,以下是相关代码
1.添加包依赖 注:aspectj版本过低会导致无法识别execution表达式
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.9</version>
</dependency>
2.配置文件
<aop:aspectj-autoproxy proxy-target-class="true"/>
proxy-target-class强制类代理,可以避免无接口类的代理失败
因为我还要统计Controller层的方法,所以此处强制使用类代理
3.代码
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author MissNull
* @Description:
* @Date: Created in 2017/8/14.
*/
@Aspect
@Component
public class PrintTime {
private Map<Long, Map<String, List<Long>>> threadMap = new ConcurrentHashMap<>(200);
@Pointcut(value = "execution(* com.ai.shop.controller..*.*(..))")
public void controller() {
}
@Pointcut(value = "execution(* com.ai.shop.dao.impl.*.*(..))")
public void dao() {
}
@Pointcut(value = "execution(* com.ai.shop.services.impl.*.*(..))")
public void service() {
}
@Before(value = "controller() || dao() || service()")
public void before(JoinPoint joinPoint) {
System.out.println(joinPoint.toShortString() + " 开始");
Map<String, List<Long>> methodTimeMap = threadMap.get(Thread.currentThread().getId());
List<Long> list;
if (methodTimeMap == null) {
methodTimeMap = new HashMap<>();
list = new LinkedList<>();
list.add(System.currentTimeMillis());
methodTimeMap.put(joinPoint.toShortString(), list);
threadMap.put(Thread.currentThread().getId(), methodTimeMap);
} else {
list = methodTimeMap.get(joinPoint.toShortString());
if (list == null) list = new LinkedList<>();
list.add(System.currentTimeMillis());
methodTimeMap.put(joinPoint.toShortString(), list);
}
}
@After(value = "controller() || dao() || service()")
public void after(JoinPoint joinPoint) {
System.out.println(joinPoint.toShortString() + " 结束");
Map<String, List<Long>> methodTimeMap = threadMap.get(Thread.currentThread().getId());
List<Long> list = methodTimeMap.get(joinPoint.toShortString());
System.out.println("耗时:" +
(System.currentTimeMillis() - list.get(list.size() - 1)));
list.remove(list.size() - 1);
}
}
4.也可以在配置文件中声明,不用注解
<aop:config> <aop:pointcut id="allMethod" expression="execution(* com.ai.*.*.*.*(..))"/> <aop:aspect ref="printTime"> <aop:before method="before" pointcut-ref="allMethod"/> <aop:after method="after" pointcut-ref="allMethod"/> </aop:aspect> </aop:config>