2021SC@SDUSC
文章目录
一、实现步骤
1,定义业务接口
JDK 代理 : 基于接口的动态代理技术
目标对象必须要有接口,代理对象通过接口动态生成的
package service;
public interface Service
{
public void run();
}
2,创建业务接口实现类
package service.impl;
public class ServiceImpl implements Service{
public void run(){
System.out.println("begin run!");
}
}
3,定义切面类
类中定义了若干普通方法,将作为不同的通知方法,用来增强功能。
package aspect;
@Aspect
public class MyAspect{
@Before(value = "execution(* run(..))")//所有的run方法前执行
public void myBefore(){
//就是你切面要执行的功能代码
System.out.println("前置通知, 切面功能:在目标方法之前输出执行时间:"+ new Date());
}
}
4,声明目标对象切面类对象
<!--声明目标类对象-->
<bean id="ServiceTarget" class="service.impl.ServiceImpl”/>
<!--声明切面类对象-->
<bean id="myAspect" class="aspect.MyAspect"/>
5,注册 AspectJ 的自动代理
<!--声明自动代理生成器-->
<aop:aspectj-autoproxy/>
在定义好切面 Aspect 后,需要通知 Spring 容器,让容器生成“目标类+ 切面”的代理对象。这个代理是由容器自动生成的。只需要在 Spring 配置文件中注册一个基于 aspectj 的自动代理生成器,其就会自动扫描到@Aspect 注解,并按通知类型与切入点,将其织入,并生成代理。
aop:aspectj-autoproxy/的底层是由AnnotationAwareAspectJAutoProxyCreator 实现的。从其类名就可看出,是基于 AspectJ 的注解适配自动代理生成器。
其工作原理是,aop:aspectj-autoproxy/通过扫描找到@Aspect 定义的切面类,再由切面类根据切入点找到目标类的目标方法,再由通知类型找到切入的时间点。
二、本项目的具体实现
1,业务接口
package com.sdu.nurse.service;
import com.sdu.nurse.entity.TreeData;
import java.util.List;
public interface TreeDataService
{
//获取所有树的节点及其子节点
List<TreeData> getAllTreeNodes();
//获取一级名称
List<TreeData> getFirstNodes();
//获取一级名称对应的二级名称
List<TreeData> getSecondNodes(String firstNodeName);
//获取二级名称对应的三级名称
List<TreeData> getThirdNodes(String secondNodeName);
//获取三级名称对应的四级名称
List<TreeData> getFourthNodes(String thirdNodeName);
}
2,创建业务接口实现类
package com.sdu.nurse.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sdu.nurse.dao.TreeDataDao;
import com.sdu.nurse.entity.TreeData;
import com.sdu.nurse.service.TreeDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
@Transactional
public class TreeDateServiceImpl implements TreeDataService
{
@Autowired
private TreeDataDao treeDataDao;
@Override
public List<TreeData> getAllTreeNodes() {
//获取一级节点
List<TreeData> healthTreeNodes = getFirstNodes();
//设置二级节点
healthTreeNodes.forEach(healthTreeNode->{
healthTreeNode.setChildren(getSecondNodes(healthTreeNode.getLabel()));
});
//设置三级节点
healthTreeNodes.forEach(healthTreeNode->{
healthTreeNode.getChildren().forEach(second->{
second.setChildren(getThirdNodes(second.getLabel()));
});
});
//设置四级节点
healthTreeNodes.forEach(healthTreeNode->{
healthTreeNode.getChildren().forEach(second->{
second.getChildren().forEach(third->{
third.setChildren(getFourthNodes(third.getLabel()));
});
});
});
return healthTreeNodes;
}
@Override
public List<TreeData> getFirstNodes() {
return treeDataDao.getAllFirstNodes();
}
@Override
public List<TreeData> getSecondNodes(String firstNodeName) {
return treeDataDao.getAllSecondNodes(firstNodeName);
}
@Override
public List<TreeData> getThirdNodes(String secondNodeName) {
return treeDataDao.getAllThirdNodes(secondNodeName);
}
@Override
public List<TreeData> getFourthNodes(String thirdNodeName) {
return treeDataDao.getALlFourthNodes(thirdNodeName);
}
}
3,定义切面类
package com.stuPayment.util;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Aspect
@Component
public class WebLogAspect {
private final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
@Pointcut("execution(public * com.sdu.nurse.service..*.*(..))")//切入点描述 这个是controller包的切入点
public void controllerLog(){}//签名,可以理解成这个切入点的一个名称
@Pointcut("execution(public * com.sdu.nurse.service..*.*(..))")//切入点描述,这个是uiController包的切入点
public void uiControllerLog(){}
@Before("controllerLog() || uiControllerLog()") //在切入点的方法run之前要干的
public void logBeforeController(JoinPoint joinPoint) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();//这个RequestContextHolder是Springmvc提供来获得请求的东西
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
// 记录下请求内容
logger.info("################URL : " + request.getRequestURL().toString());
logger.info("################HTTP_METHOD : " + request.getMethod());
logger.info("################IP : " + request.getRemoteAddr());
logger.info("################THE ARGS OF THE CONTROLLER : " + Arrays.toString(joinPoint.getArgs()));
logger.info("################CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
}
}