使用aop自定义注解实现日志管理,页面调用自定义注解无效???

木有有 2017-01-03 07:11:38
自定义注解类:
package cn.xaele.aspect.annotation;
import java.lang.annotation.*;

/**
*自定义注解 拦截Controller
*/

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String description() default "";
}
切面类:
package cn.xaele.aspect.annotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
* 切面类
*/
@Aspect
@Component
public class SystemLogAspect {
//本地异常日志记录对象
private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);

//Service层切点
@Pointcut("@annotation(cn.xaele.aspect.annotation.SystemServiceLog)")
public void serviceAspect() {
}

//Controller层切点
@Pointcut("@annotation(cn.xaele.aspect.annotation.SystemControllerLog)")
public void controllerAspect() {
}

/**
* 前置通知 用于拦截Controller层记录用户的操作
*
* @param joinPoint 切点
*/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) {

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
// //读取session中的用户
// User user = (User) session.getAttribute(WebConstants.CURRENT_USER);
//请求的IP
String ip = request.getRemoteAddr();
try {
//*========控制台输出=========*//
System.out.println("=====前置通知开始=====");
System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));
// System.out.println("请求人:" + user.getName());
System.out.println("请求IP:" + ip);
System.out.println("=====前置通知结束=====");
} catch (Exception e) {
//记录本地异常日志
logger.error("==前置通知异常==");
logger.error("异常信息:{}", e.getMessage());
}
}
//省略getControllerMethodDescription()方法
}
Controller类:
package cn.xaele.kq.psm.ctrl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.xaele.aspect.annotation.SystemControllerLog;
import cn.xaele.comm.page.Pagination;
import cn.xaele.comm.web.DataGrid;
import cn.xaele.comm.web.JsonData;
import cn.xaele.ctrl.BaseCtrl;
import cn.xaele.kq.psm.bean.KqWorkType;
import cn.xaele.kq.psm.srvc.KqWorkTypeSrvc1;
import cn.xaele.kq.psm.vo.KqWorkTypeVo;
import cn.xaele.page.PageUtils;

/**
* “工种” 用户操作控制类
*
* @author taotao
* @since 2015-10-21 23:09
* @version 1.0.0
*/
@Controller
@RequestMapping("/workTypeCtrl")
public class KqWorkTypeCtrl1 extends BaseCtrl {

/**
* 功能入口,转向列表页面
* @param request
* @return
* @throws Exception
*/
@SystemControllerLog(description = "功能入口")
@RequestMapping("/toList")
public ModelAndView toList()throws Exception{
ModelAndView mv = new ModelAndView("/kq/psm/KqWorkTypeList");
return mv;
}
...
}
Controller类的入口方法toList()添加注解@SystemControllerLog(description = "功能入口")

spring mvc.xml:
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
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-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<!--
配置文件分开的原因(摘录):
通常情况下, 类似于数据源, 事务, 整合其他框架都是放在 Spring 的配置文件中(而不是放在 SpringMVC 的配置文件中).
实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao等。把配置文件分为spring.xml和spring-mvc.xml,一是结构比较清晰,而是方便项目后期内扩展(spring集成
第三方框架)
配置文件分开带来的问题:若 Spring 的 IOC 容器和 SpringMVC 的 IOC 容器扫描的包有重合的部分,web容器启动过程中, 就会导致所有的 bean 会被创建 2 次.
解决:
使用 exclude-filter 和 include-filter 子节点来规定只能扫描的注解,使 Spring 的 IOC 容器扫描的包和 SpringMVC 的 IOC 容器扫描的包没有重合的部分.
-->
<!-- 启用MVC注解 -->
<mvc:annotation-driven/>

<!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>

<!-- 通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->
<aop:config proxy-target-class="true"></aop:config>

<!-- 如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。 -->
<mvc:default-servlet-handler default-servlet-name="HRAttendApp" />

<!-- 自动扫描的包.只用来扫描controller,use-default-filters设置成false才能让注解事务起作用 -->
<context:component-scan base-package="cn.xaele" use-default-filters="false">
<!-- IOC容器只扫描包含@Controller和@ControllerAdvice注解的类 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

<!-- 配置视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<!--
上面的配置是固定的,下面两个配置意思是:如果你要访问index视图,
它会自动 prefix(前缀) + index + suffix(后缀),
生成/WEB-INF/views/index.jsp
-->
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

<!-- 配置国际化资源文件 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="ApplicationResources"></property>
</bean>

<!-- 配置文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上面配置是固定的,下面是配置上传文件的最大大小 -->
<property name="maxUploadSize" value="204800000"/>
</bean>
</beans>
spring-mvc.xml也加了:
<!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>

<!-- 通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller -->
<aop:config proxy-target-class="true"></aop:config>



测试类:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.xaele.kq.psm.ctrl.KqWorkTypeCtrl;
import cn.xaele.kq.psm.ctrl.KqWorkTypeCtrl1;
import cn.xaele.kq.psm.srvc.KqWorkTypeSrvc1;

/**
* <p>Title:TestAspect</p>
* <p>Description:描述...</p>
* <p>Company:西安...</p>
* @author YangYuan
* @date 2016年12月31日 上午11:26:57
* @version 1.0
* @Copyright Xuang Ele All right reserved
*/
public class TestAspect {
public static void main(String[] args) throws Exception {
//1、创建IOC容器的实例
ApplicationContext ctx = new ClassPathXmlApplicationContext
(new String[]{"classpath:spring.xml","classpath:spring-mvc.xml"});
//2、从IOC容器中获取bean的实例
KqWorkTypeCtrl1 workTypeCtrl1 = ctx.getBean(KqWorkTypeCtrl1.class);
//3、使用bean
workTypeCtrl1.toList();
}
}
使用测试类从IOC对象中获取controller对象,再调用toList()方法,注解就生效。问题是启动web容器,登录系统点击相应的菜单注解无论如何他也不生效,一模一样的配置放到别的项目上就可以,折腾了两天了还是不行,真是打不死的小强,求大神指点迷津。和另我一个项目比,jsp页调用toList()方法时没有.do .action之类的后缀,应该与这个没关系吧。另外spring.xml
spring-mvc.xml中自动扫描的包没有重复,web容器启动的时候 ,IOC容器中 的对象都是加载了一次。
...全文
937 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
lr1990420 2017-11-09
  • 打赏
  • 举报
回复
楼主解决了没 <!-- 启动对@AspectJ注解的支持 --> <aop:aspectj-autoproxy/> <!-- 通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller --> <aop:config proxy-target-class="true"></aop:config> 打开cglib代理需要放到spring-mvc配置文件中,不要只放到spring的配置文件里

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧