欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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;
	}

}