Spring AOP面向切面编程
程序员文章站
2022-06-04 22:04:59
...
AOP面向切面,通过预编译和运行期动态代理实现程序功能的统一维护
AOP可以使业务各个部分隔离,使业务耦合降低,提升重用性和开发效率
面向接口编程
public interface StudentService {
public void addStudent(String name);
}
实现类
public class StudentServiceImpl implements StudentService{
@Override
public void addStudent(String name) {
// System.out.println("开始添加学生"+name);
System.out.println("添加学生"+name);
// System.out.println("完成学生"+name+"的添加");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="studentService" class="com.java.service.impl.StudentServiceImpl"></bean>
</beans>
接口多态
父类的引用直接指向具体的实现
接口调用add方法
public class T {
private ApplicationContext ac;
@Before
public void setUp() throws Exception {
ac=new ClassPathXmlApplicationContext("beans.xml");
}
@Test
public void test1() {
StudentService studentService=(StudentService)ac.getBean("studentService");
studentService.addStudent("张三");
}
}
日志记录
前置通知,后置通知,环绕通知,返回通知,异常通知
前置通知执行方法前执行操作
public class StudentServiceAspect {
public void doBefore(JoinPoint jp){
System.out.println("类名:"+jp.getTarget().getClass().getName());
System.out.println("方法名:"+jp.getSignature().getName());
System.out.println("开始添加学生:"+jp.getArgs()[0]);
}
}
aop:aspect 定义切面类
aop:pointcut 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: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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="studentServiceAspect" class="com.java.advice.StudentServiceAspect"></bean>
<aop:config>
<aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
<aop:pointcut expression="execution(* com.java.service.*.*(..))" id="businessService"/>
<aop:before method="doBefore" pointcut-ref="businessService"/>
<aop:after method="doAfter" pointcut-ref="businessService"/>
<aop:around method="doAround" pointcut-ref="businessService"/>
<aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/>
<aop:after-throwing method="doAfterThrowing" pointcut-ref="businessService" throwing="ex"/>
</aop:aspect>
</aop:config>
</beans>
上面的配置已经把service都扫描进去,在执行addService的时候通过配置aop;before 通过代理先执行doBefore方法
public class StudentServiceImpl implements StudentService{
@Override
public void addStudent(String name) {
System.out.println("添加学生"+name);
System.out.println(1/0);
}
}
切面类的其他通知
环绕通知doAround有返回值为addStudent方法的返回值,当要执行方法时候先执行proceed调用代理执行业务的方法
返回通知 方法要返回return之前的通知,方法还没有执行完
异常通知 Throwable 异常解析
public void doAfter(JoinPoint jp){
System.out.println("类名:"+jp.getTarget().getClass().getName());
System.out.println("方法名:"+jp.getSignature().getName());
System.out.println("学生添加完成:"+jp.getArgs()[0]);
}
public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("添加学生前");
Object retVal=pjp.proceed();
System.out.println(retVal);
System.out.println("添加学生后");
return retVal;
}
public void doAfterReturning(JoinPoint jp){
System.out.println("返回通知");
}
public void doAfterThrowing(JoinPoint jp,Throwable ex){
System.out.println("异常通知");
System.out.println("异常信息:"+ex.getMessage());
}
通过注解获取积分
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;
//@Aspect
//@Component
public class InterceptorAspect {
protected static final int AdapterEntity = 0;
private ExecutorService pool = Executors.newFixedThreadPool(100);
@Autowired
private CntenInterceptorCacheManagerImpl interceptorCacheManagerImpl;
private HttpServletRequest request;
private AdapterFactory factory = new AdapterFactory();
@Pointcut("execution (* com..controller..*.*(..))")
public void controllerAspect() {
}
@Autowired
private IntegralService integralService = null;
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) {
}
@AfterReturning(returning = "rvt", pointcut = "controllerAspect()")
public Object AfterExec(final JoinPoint joinPoint, final Object rvt) {
request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
final WebApplicationContext content = WebApplicationContextUtils
.getWebApplicationContext(request.getServletContext());
String signature = joinPoint.getSignature().toString().replace("String", "");
String ruleStr = signature.substring(0, signature.indexOf("(")).trim();
final String actionStr = ruleStr.substring(ruleStr.indexOf("controller.") + 11, ruleStr.length());
if (request != null) {
final User user = (User) request.getSession().getAttribute(LoginConstant.LOGIN_USER_SESSION_KEY);
final String codesStr = interceptorCacheManagerImpl.get(CntenInterceptorCacheManagerImpl.cacheName,
request.getSession().getId());
if (user != null && !StringUtil.isEmpty(codesStr) && codesStr.contains(actionStr)) {
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(this.hashCode());
// factory.setRequest(request);
// factory.setUser(user);
List<integralRule> integralRules = interceptorCacheManagerImpl.get(
CntenInterceptorCacheManagerImpl.cacheName, request.getSession().getId() + "_data");
integralRule integralRule = null;
for (integralRule rule : integralRules) {
if (rule.getIntegralActionCode().contains(actionStr)) {
integralRule = rule;
break;
}
}
String adapterClassNames = "";// 积分规则的适配器
if (integralRule != null) {
adapterClassNames = integralRule.getIntegralAdapter();
// factory.setIntegralRule(integralRule);
}
String[] classNameArray = adapterClassNames.split(",");
AbstractInterceptorAdapter adapter = null;
for (String className : classNameArray) {
try {
Method createMethod = factory.getClass().getMethod("get" + className.trim());
adapter = (AbstractInterceptorAdapter) createMethod.invoke(factory);
Field field = adapter.getClass().getSuperclass().getDeclaredField("entity");
field.setAccessible(true);
AdapterEntity entity = new AdapterEntity();
entity.setApplicationContext(content);
entity.setRequest(request);
entity.setUser(user);
entity.setRuleCodes(codesStr);
entity.setCusCode(actionStr);
entity.setIntegralRules(integralRules);
entity.setIntegralService(integralService);
entity.setIntegralRule(integralRule);
entity.setData(rvt);
entity.setJoinPoint(joinPoint);
field.set(adapter, entity);
if (adapter != null) {
adapter.processingIntegral();
}
adapter.clearEntity();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
}
}
return rvt;
}
/**
* 判断切点是否执行成功
* @param rvt
* @return
*/
public boolean checkReturn(Object rvt) {
if(rvt instanceof AssembleJSON) {
AssembleJSON json = (AssembleJSON) rvt;
if(json.getStatus()!=1000) {
return false;
}
}
return true;
}
/**
* 根据参数判断是否需要进行添加积分
* @param orgs
* @return
*/
public boolean checkArgs(Object[] args) {
boolean isSUccess = false;
if(args != null && args.length >0) {
Object dataArg = null;
for (Object arg : args) {
String[] classArray = arg.getClass().getName().split(".");
if("model".equals(classArray[classArray.length-1])) {
dataArg = arg;
break;
}
}
if(dataArg!=null) {
}
}
return isSUccess;
}
}
下一篇: 给ecshop添加可选择多语言