第一,注解:
@Before – 目标方法执行前执行
@After – 目标方法执行后执行
@AfterReturning – 目标方法返回后执行,如果发生异常不执行
@AfterThrowing – 异常时执行
@Around – 在执行上面其他操作的同时也执行这个方法
第二,SpringMVC如果要使用AOP注解,必须将放在spring-servlet.xml(配置MVC的XML)中
<
aop:aspectj-autoproxy
proxy-target-class
=
"true"
/>
|
项目截图
首先是Maven依赖
<
properties
>
<
springframework
>4.0.5.RELEASE
springframework
>
<
aspectj
>1.8.5
aspectj
>
<
servlet
>3.1.0
servlet
>
properties
>
<
dependencies
>
<
dependency
>
<
groupId
>javax.servlet
groupId
>
<
artifactId
>javax.servlet-api
artifactId
>
<
version
>${servlet}
version
>
<
scope
>compile
scope
>
dependency
>
<
dependency
>
<
groupId
>org.springframework
groupId
>
<
artifactId
>spring-webmvc
artifactId
>
<
version
>${springframework}
version
>
dependency
>
<
dependency
>
<
groupId
>org.springframework
groupId
>
<
artifactId
>spring-aop
artifactId
>
<
version
>${springframework}
version
>
dependency
>
<
dependency
>
<
groupId
>org.aspectj
groupId
>
<
artifactId
>aspectjrt
artifactId
>
<
version
>${aspectj}
version
>
dependency
>
<
dependency
>
<
groupId
>org.aspectj
groupId
>
<
artifactId
>aspectjweaver
artifactId
>
<
version
>${aspectj}
version
>
dependency
>
dependencies
>
|
spring-context.xml配置,基本无内容
<
context:component-scan
base-package
=
"org.xdemo.example.springaop"
>
<
context:exclude-filter
type
=
"annotation"
expression
=
"org.springframework.stereotype.Controller"
/>
context:component-scan
>
|
spring-mvc.xml配置
<
aop:aspectj-autoproxy
proxy-target-class
=
"true"
/>
<
mvc:annotation-driven
/>
<
context:component-scan
base-package
=
"org.xdemo.example.springaop"
>
<
context:include-filter
type
=
"annotation"
expression
=
"org.springframework.stereotype.Controller"
/>
context:component-scan
>
|
Web.xml配置
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
web-app
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://java.sun.com/xml/ns/javaee"
xmlns:web
=
"http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation
=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version
=
"3.0"
>
<
display-name
>Archetype Created Web Application
display-name
>
<
context-param
>
<
param-name
>webAppRootKey
param-name
>
<
param-value
>org.xdemo.example.springaop
param-value
>
context-param
>
<
context-param
>
<
param-name
>contextConfigLocation
param-name
>
<
param-value
>classpath:spring-context.xml
param-value
>
context-param
>
<
listener
>
<
listener-class
>org.springframework.web.context.ContextLoaderListener
listener-class
>
listener
>
<
servlet
>
<
servlet-name
>SpringMVC
servlet-name
>
<
servlet-class
>org.springframework.web.servlet.DispatcherServlet
servlet-class
>
<
init-param
>
<
param-name
>contextConfigLocation
param-name
>
<
param-value
>classpath:spring-mvc.xml
param-value
>
init-param
>
<
load-on-startup
>1
load-on-startup
>
servlet
>
<
servlet-mapping
>
<
servlet-name
>SpringMVC
servlet-name
>
<
url-pattern
>/
url-pattern
>
servlet-mapping
>
web-app
>
|
注解Log
package
org.xdemo.example.springaop.annotation;
import
java.lang.annotation.ElementType;
import
java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy;
import
java.lang.annotation.Target;
@Retention
(RetentionPolicy.RUNTIME)
@Target
({ ElementType.METHOD })
public
@interface
Log {
String name()
default
""
;
}
|
日志AOP,写法一LogAop_1
package
org.xdemo.example.springaop.aop;
import
java.lang.reflect.Method;
import
java.util.UUID;
import
org.aspectj.lang.JoinPoint;
import
org.aspectj.lang.ProceedingJoinPoint;
import
org.aspectj.lang.annotation.After;
import
org.aspectj.lang.annotation.Around;
import
org.aspectj.lang.annotation.Aspect;
import
org.aspectj.lang.annotation.Before;
import
org.aspectj.lang.reflect.MethodSignature;
import
org.springframework.stereotype.Component;
import
org.xdemo.example.springaop.annotation.Log;
@Aspect
@Component
public
class
LogAop_1 {
ThreadLocal
new
ThreadLocal
ThreadLocal
new
ThreadLocal
/**
* 在所有标注@Log的地方切入
* @param joinPoint
*/
@Before
(
"@annotation(org.xdemo.example.springaop.annotation.Log)"
)
public
void
beforeExec(JoinPoint joinPoint){
time.set(System.currentTimeMillis());
tag.set(UUID.randomUUID().toString());
info(joinPoint);
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println(method.getAnnotation(Log.
class
).name()+
"标记"
+tag.get());
}
@After
(
"@annotation(org.xdemo.example.springaop.annotation.Log)"
)
public
void
afterExec(JoinPoint joinPoint){
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println(
"标记为"
+tag.get()+
"的方法"
+method.getName()+
"运行消耗"
+(System.currentTimeMillis()-time.get())+
"ms"
);
}
@Around
(
"@annotation(org.xdemo.example.springaop.annotation.Log)"
)
public
void
aroundExec(ProceedingJoinPoint pjp)
throws
Throwable{
System.out.println(
"我是Around,来打酱油的"
);
pjp.proceed();
}
private
void
info(JoinPoint joinPoint){
System.out.println(
"--------------------------------------------------"
);
System.out.println(
"King:\t"
+joinPoint.getKind());
System.out.println(
"Target:\t"
+joinPoint.getTarget().toString());
Object[] os=joinPoint.getArgs();
System.out.println(
"Args:"
);
for
(
int
i=
0
;i
System.out.println(
"\t==>参数["
+i+
"]:\t"
+os[i].toString());
}
System.out.println(
"Signature:\t"
+joinPoint.getSignature());
System.out.println(
"SourceLocation:\t"
+joinPoint.getSourceLocation());
System.out.println(
"StaticPart:\t"
+joinPoint.getStaticPart());
System.out.println(
"--------------------------------------------------"
);
}
}
|
日志AOP,写法二LogAop_2
package
org.xdemo.example.springaop.aop;
import
java.lang.reflect.Method;
import
java.util.UUID;
import
org.aspectj.lang.JoinPoint;
import
org.aspectj.lang.ProceedingJoinPoint;
import
org.aspectj.lang.annotation.After;
import
org.aspectj.lang.annotation.Around;
import
org.aspectj.lang.annotation.Aspect;
import
org.aspectj.lang.annotation.Before;
import
org.aspectj.lang.annotation.Pointcut;
import
org.aspectj.lang.reflect.MethodSignature;
import
org.springframework.stereotype.Component;
import
org.xdemo.example.springaop.annotation.Log;
@Aspect
@Component
public
class
LogAop_2 {
ThreadLocal
new
ThreadLocal
ThreadLocal
new
ThreadLocal
@Pointcut
(
"@annotation(org.xdemo.example.springaop.annotation.Log)"
)
public
void
log(){
System.out.println(
"我是一个切入点"
);
}
/**
* 在所有标注@Log的地方切入
* @param joinPoint
*/
@Before
(
"log()"
)
public
void
beforeExec(JoinPoint joinPoint){
time.set(System.currentTimeMillis());
tag.set(UUID.randomUUID().toString());
info(joinPoint);
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println(method.getAnnotation(Log.
class
).name()+
"标记"
+tag.get());
}
@After
(
"log()"
)
public
void
afterExec(JoinPoint joinPoint){
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println(
"标记为"
+tag.get()+
"的方法"
+method.getName()+
"运行消耗"
+(System.currentTimeMillis()-time.get())+
"ms"
);
}
@Around
(
"log()"
)
public
void
aroundExec(ProceedingJoinPoint pjp)
throws
Throwable{
System.out.println(
"我是Around,来打酱油的"
);
pjp.proceed();
}
private
void
info(JoinPoint joinPoint){
System.out.println(
"--------------------------------------------------"
);
System.out.println(
"King:\t"
+joinPoint.getKind());
System.out.println(
"Target:\t"
+joinPoint.getTarget().toString());
Object[] os=joinPoint.getArgs();
System.out.println(
"Args:"
);
for
(
int
i=
0
;i
System.out.println(
"\t==>参数["
+i+
"]:\t"
+os[i].toString());
}
System.out.println(
"Signature:\t"
+joinPoint.getSignature());
System.out.println(
"SourceLocation:\t"
+joinPoint.getSourceLocation());
System.out.println(
"StaticPart:\t"
+joinPoint.getStaticPart());
System.out.println(
"--------------------------------------------------"
);
}
}
|
用到的一个用户类User
package
org.xdemo.example.springaop.bean;
public
class
User {
private
String name;
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
}
|
一个测试的Controller
package
org.xdemo.example.springaop.controller;
import
javax.annotation.Resource;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.ResponseBody;
import
org.xdemo.example.springaop.annotation.Log;
import
org.xdemo.example.springaop.bean.User;
import
org.xdemo.example.springaop.service.IUserService;
@Controller
@RequestMapping
(
"/aop"
)
public
class
SpringController {
@Resource
IUserService userService;
@Log
(name=
"您访问了aop1方法"
)
@ResponseBody
@RequestMapping
(value=
"aop1"
)
public
String aop1(){
return
"AOP"
;
}
@Log
(name=
"您访问了aop2方法"
)
@ResponseBody
@RequestMapping
(value=
"aop2"
)
public
String aop2(String string)
throws
InterruptedException{
Thread.sleep(1000L);
User user=
new
User();
user.setName(string);
userService.save(user);
return
string;
}
}
|
一个测试的接口实现类(接口类略)
package
org.xdemo.example.springaop.service;
import
org.springframework.stereotype.Service;
import
org.xdemo.example.springaop.annotation.Log;
import
org.xdemo.example.springaop.bean.User;
@Service
public
class
UserServiceImpl
implements
IUserService {
@Log
(name =
"您访问了保存用户信息"
)
public
void
save(User user) {
System.out.println(user.getName());
}
}
|