1.全注解配置
所需jar包
<!--mybatis的jar包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--數(shù)據(jù)庫連接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--spring上下文容器-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--spring整合jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--druid連接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!--mybatis整合spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!--spring整合JUnit測試-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--JUnit測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--aspect切面-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
service層接口
public interface UserService {
public void add();
public void delete();
public void update();
public void find();
}
service層接口的實現(xiàn)類
@Configuration
@Service("userService")
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("新增用戶");
}
public void delete() {
System.out.println("刪除用戶");
}
public void update() {
System.out.println("更新用戶");
}
public void find() {
System.out.println("查詢用戶");
}
}
spring的配置類
@Configuration
@ComponentScan("com.*")
@EnableAspectJAutoProxy
public class SpringConfig {}
編寫注解通知順序類
@Component("logAdvice")
@Aspect
public class LogAdvice {
//切入點-用于將方法插入
//此方法也可以抽取成父類
@Pointcut("execution(* com.*.service.impl.*.*(..))")
public void pt1(){}
//在插入目標地之前執(zhí)行
@Before("pt1()")
public void beforeLog(JoinPoint joinPoint){
//獲取切入點方法的參數(shù)們
Object[] args = joinPoint.getArgs();
System.out.println(Arrays.asList(args));
//獲取目標對象的類名
String simpleName = joinPoint.getTarget().getClass().getSimpleName();
String name = joinPoint.getSignature().getName();
System.out.println(simpleName+":"+name+"方法執(zhí)行后");
}
//在執(zhí)行目標地的方法后執(zhí)行此方法
@AfterReturning("pt1()")
public void afterReturningLog(JoinPoint joinPoint){
//獲取目標對象的類名
String simpleName = joinPoint.getTarget().getClass().getSimpleName();
String name = joinPoint.getSignature().getName();
System.out.println(simpleName+":"+name+"方法執(zhí)行后");
}
// 目的地方法正常執(zhí)行后執(zhí)行
@After("pt1()")
public void afterLog(JoinPoint joinPoint){
//獲取目標對象的類名
String simpleName = joinPoint.getTarget().getClass().getSimpleName();
String name = joinPoint.getSignature().getName();
System.out.println(simpleName+":"+name+"方法執(zhí)行結(jié)束");
}
//目的地方法執(zhí)行時拋出異常后執(zhí)行
@AfterThrowing(value = "pt1()",throwing = "e")
public void afterThrowingLog(JoinPoint joinPoint, Throwable e){
//獲取目標對象的類名
String simpleName = joinPoint.getTarget().getClass().getSimpleName();
//獲取切入點方法名
String methodName = joinPoint.getSignature().getName();
System.out.println(simpleName+"的"+methodName+"方法執(zhí)行產(chǎn)生異常后,異常為:"+e.getMessage());
}
//環(huán)繞--此方法可以代替其余所有方法
//其中代碼執(zhí)行的順序有自己指定,順序和try-catch-finally一致
public Object aroundLog(ProceedingJoinPoint pjp){
String simpleName = pjp.getTarget().getClass().getSimpleName();
Signature signature = pjp.getSignature();
String methodName = signature.getName();
try {
// 前置
System.out.println(simpleName+"的"+methodName+"方法執(zhí)行前");
Object rtValue = pjp.proceed();
//后置
System.out.println(simpleName+"的"+methodName+"方法正常執(zhí)行后");
return rtValue;
} catch(Throwable throwable){
System.out.println("Exception 異常");
// 異常
System.out.println(simpleName+"的"+methodName+"方法執(zhí)行產(chǎn)生異常后");
return null;
} finally{
// 最終
System.out.println(simpleName+"的"+methodName+"方法最終執(zhí)行結(jié)束");
}
}
}
2.spring代理
由上述的userServiceImpl舉例
public class UserServiceImlp{
public void save(){
System.out.println("水泥墻");
}
}
提供一個方法,用于指定對象的代理對象
class UserServiceCglibProxy{
//如果你的jdk版本高于1.8這里的實現(xiàn)類不用寫final
public static UserServiceImpl2 createUserServiceCglibProxy(final UserServiceImpl2 userService){
UserServiceImpl2 userServiceProxy = (UserServiceImpl2) Enhancer.create(userService.getClass(), new MethodInterceptor() {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if (method.getName().equals("save")){
//調(diào)用原始的父類方法...
Long startTime = 0L;
Date date = new Date();
startTime = date.getTime();
userService.find();
Object rtValue = method.invoke(userService, args);
Long endTime = date.getTime();
System.out.println("阿巴阿巴");
System.out.println(endTime-startTime);
return rtValue;
}
// 其它方法,原封不動的調(diào)用
return method.invoke(userService, args);
}
});
return userServiceProxy;
}
}
測試代碼
public static void main(String[] args) {
UserServiceImpl2 userServiceImpl = new UserServiceImpl2();
UserServiceImpl2 userService = UserServiceCglibProxy.createUserServiceCglibProxy(userServiceImpl);
userService.save();
}
切入點表達式
execution(*
execution(*
execution(public
*
execution(public
int
execution(public
void
execution(public
void com..*.*(..))
execution(public
void com..service
execution(public
void com.itheima.service
execution(public
void com.itheima.service.User
execution(public
void com.itheima.service .*
execution(public
void com.itheima.service.UserService
execution(public
User com.itheima.service.UserService.find
execution(public
User com.itheima.service.UserService .*
execution(public
User com.itheima.service.UserService.findById
execution(public
User com.itheima.service.UserService.findById int
execution(public
User com.itheima.service.UserService.findById int,int
execution(public
User com.itheima.service.UserService.findById int
execution(public
User com.itheima.service.UserService.findById int
execution(public
User com.itheima.service.UserService.findById
execution(List
com.itheima.service .* findAll