Spring AOP
面向切面编程
AOP其实只是OOP的补充而已。OOP从横向上区分出一个个的类来,而AOP则从纵向上向对象中加入特定的代码。
通过预编译的方式和运行期间动态代理实现程序的统一维护的一种技术,主要功能是、日志记录、性能同级、安全控制、事务处理等。
比如:在ssm框架中我们不用手动去提交事物,并不是不需要们我去提交,而是Spring框架在增删改的时候利用AOP提交了事物。
以下通过一些简单配置实现日志的记录
pom.xml配置
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
spring.xml配置
<!--面线切面-->
<aop:aspectj-autoproxy/>
自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
String desc() default "";
}
在此我们还要创建一下日志表(ID,用户,日志信息,时间),用自动生成生成一下实体类和mapper。
接着我们要定义切点和考虑在和在什么时候处理这个切点
@Component
@Aspect
public class SystemLogAspect {
@Autowired
private SystemLogService systemLogService;
//切点 拦截 类中loginPost的方法 参数表示任意参数
//@Pointcut("execution(public * com.crm.controller.LoginController.*(..))")
@Pointcut("@annotation(com.crm.aop.SystemLog)")
public void serviceAspect() {
}
@After("serviceAspect()")
public void doOperation(JoinPoint joinPoint){
//获得request对象
HttpServletRequest request =
((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
//获得user对象
User user = (User)session.getAttribute("user");
if (user!=null){
SystemLog systemLog = new SystemLog();
systemLog.setCreateUser(user.getUserName());
systemLog.setCreateTime(new Date());
systemLog.setLogContent(getDesc(joinPoint));
systemLogService.insertSystemLog(systemLog);
}
}
//获得自定义注解的内容
private String getDesc(JoinPoint joinPoint){
String desc="";
//获取类和方法名
String methodName = joinPoint.getSignature().getName();
String className = joinPoint.getTarget().getClass().getName();
try {
//通过java 反射获得 类的方法名
Class reClass = Class.forName(className);
for (Method m: reClass.getMethods()) {
if (m.getName().equals(methodName)){
//获得注解字符串
desc = m.getAnnotation(com.crm.aop.SystemLog.class).desc();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return desc;
}
}
AOP 除了@after 还有@before 和@around
接下来我们去控制层加上自定义注解
@RequestMapping(value = "checkUserName.shtml",method = RequestMethod.POST)
@ResponseBody
@SystemLog(desc = "添加了用户")
public Message checkUserNamePost(User user){
Message<User> message = new Message();
user = userService.findUserByUserName(user);
if (user!=null&&user.getUserName()!=null&&user.getUserName().length()>0){
message.setState(1);
message.setContent(user);
}else{
message.setState(0);
message.setContent(null);
}
return message;
}
使用java反射获得desc的字符串,然后存储到数据库中。