Spring学习(七)

面向切面编程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.xiaoguan.biz;

import org.aspectj.lang.JoinPoint;
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.text.SimpleDateFormat;
import java.util.Date;
@Component
@Aspect
public class SecurityAspect {
@Pointcut("execution(* com.xiaoguan.biz..save*(..))")
public void savePointcut(){

}
@Pointcut("execution(* com.xiaoguan.biz..delete*(..))")
public void deletePointcut(){

}
@Pointcut("execution(* com.xiaoguan.biz..update*(..))")
public void updatePointcut(){

}
@Pointcut("execution(* com.xiaoguan.biz..select*(..))")
public void selectPointcut(){

}
@Before("savePointcut()||deletePointcut()||updatePointcut()||selectPointcut()")
public void beforeAdvice(JoinPoint joinPoint){
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SS");
String nowTime = simpleDateFormat.format(new Date());
System.out.println(nowTime+"张三:"+joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.xiaoguan.biz;

import org.springframework.stereotype.Service;

@Service
public class UserService {
public void saveUser(){
System.out.println("新增用户");
}
public void deleteUser(){
System.out.println("删除用户");
}
public void updateUser(){
System.out.println("更改用户");
}
public void selectUser(){
System.out.println("查询用户");
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.xiaoguan.biz;

import org.springframework.stereotype.Service;

@Service
public class VipService {
public void saveUser(){
System.out.println("新增会员用户");
}
public void deleteUser(){
System.out.println("删除会员用户");
}
public void updateUser(){
System.out.println("更改会员用户");
}
public void selectUser() {
System.out.println("查询会员用户");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.xiaoguan.service;

import org.springframework.stereotype.Service;

@Service
public class AccountService {
public void transfer(){
System.out.println("银行账户正在进行转账操作");
}
public void withdraw(){
System.out.println("银行账户正在取款,请稍后");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.xiaoguan.service;

import org.springframework.stereotype.Service;

@Service
public class OrderService {

public void generate(){
System.out.println("正在生成订单");
}
public void cancel(){
System.out.println("订单已经取消");
String s=null;
s.toString();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.xiaoguan.service;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Component
@Aspect

public class TransactionAspect {
@Around("execution(* com.xiaoguan.service..*(..))")
public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
try {
System.out.println("开启事务");
proceedingJoinPoint.proceed();
System.out.println("提交事务");

} catch (Throwable e) {
System.out.println("回滚事务");
e.printStackTrace();
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.xiaoguan"/>
<aop:aspectj-autoproxy/>

</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.xiaoguan.test;

import com.xiaoguan.biz.UserService;
import com.xiaoguan.biz.VipService;
import com.xiaoguan.service.AccountService;
import com.xiaoguan.service.OrderService;
import org.aspectj.lang.annotation.Aspect;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AOPRealAPPTest {
@Test
public void testSecurityLog(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userService", UserService.class);
VipService vipService = applicationContext.getBean("vipService", VipService.class);
userService.deleteUser();
vipService.saveUser();
}
@Test
public void testTransaction(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
AccountService accountService = applicationContext.getBean("accountService", AccountService.class);
OrderService orderService = applicationContext.getBean("orderService", OrderService.class);
accountService.transfer();
accountService.withdraw();
orderService.generate();
orderService.cancel();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.xiaoguan.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(2)
public class LogAspect {
@Pointcut("execution(* com.xiaoguan.service..*(..))")
public void 通用切点(){
System.out.println("通用切点");

}
//前置通知
@Before("通用切点()")
public void beforeAdvice(JoinPoint joinPoint){
System.out.println("前置通知");
// Signature signature = proceedingJoinPoint.getSignature();//目标方法的签名
// String name = signature.getName();
System.out.println(joinPoint.getSignature().getName());
// System.out.println(name);
}
@AfterReturning("通用切点()")
public void afterReturningAdvice(){
System.out.println("后置通知");
}
@Around("通用切点()")
public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("前环绕");
proceedingJoinPoint.proceed();
System.out.println("后环绕");
}
@After("通用切点()")
public void afterAdvice(){
System.out.println("最终通知");
}
@AfterThrowing("通用切点()")
public void afterThrowingAdvice(){//抛异常通知
System.out.println("异常通知");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.xiaoguan.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(3)
public class SecurityAspect {
@Before("execution(* com.xiaoguan.service..*(..))")
public void beforeAdvice(){
System.out.println("前置通知安全");
}
}

1
2
3
4
5
6
7
8
9
10
11
package com.xiaoguan.service;

import org.springframework.stereotype.Service;

@Service("111")
public class OrderService {
public void generate() {
System.out.println("生成订单");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
package com.xiaoguan.service;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan({"com.xiaoguan.service","com.xiaoguan.aspect"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Spring6Config {
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.xiaoguan.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {
public void login(){
System.out.println("系统正在进行身份验证");
}
public void logout(){
System.out.println("退出系统");

}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.xiaoguan.service,com.xiaoguan.aspect"/>
<!-- proxy-target-class="true"表示强制使用cglib动态代理-->
<!-- proxy-target-class="false"表示接口使用jdk动态代理,反之使用cglib动态代理-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.xiaoguan.test;

import com.xiaoguan.service.OrderService;
import com.xiaoguan.service.Spring6Config;
import com.xiaoguan.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringAopTest {
@Test
public void testNoXML(){
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(Spring6Config.class);
OrderService orderService = applicationContext.getBean("111", OrderService.class);
orderService.generate();
}
@Test
public void testBefore(){
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
// userService.login();
// userService.logout();
OrderService orderService = applicationContext.getBean("111", OrderService.class);
orderService.generate();


}
}