`
dove19900520
  • 浏览: 593074 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

利用spring mvc AOP进行日志管理 (采用注解@AspectJ)

阅读更多

      在现实的上线中我们经常会遇到系统出现异常或者问题。这个时候就马上打开CRT或者SSH连上服务器拿日子来分析。受网络的各种限制。于是我们就想为什么不能直接在管理后台查看报错的信息呢。于是日志管理就出现了。

      很早之前就有同学问我,如何用spring aop来实现日志管理的问题,现在个人觉得做日志管理最好的是Aop,当然有的人也喜欢用拦截器。

      Aop有的人说拦截不到Controller。有的人说想拦AnnotationMethodHandlerAdapter截到Controller必须得拦截org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter。首先Aop可以拦截到Controller的,这个是毋容置疑的;其次须拦截AnnotationMethodHandlerAdapter也不是必须的。Aop之所以有的人说拦截不到Controller是因为Controller被jdk代理了。我们只要把它交给cglib代理就可以了。

       废话不多说了,下面开始上代码:

 

第一步:编写两个注解

1、拦截controller的注解

package com.ctlovedove.log.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 系统级别的controller层自定义注解
 * <br>拦截Controller
 * @author ct
 *
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})//作用于参数或方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
	String description() default "";
}

 2、拦截service的注解

package com.ctlovedove.log.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 系统级别的service层自定义注解
 * <br>拦截service
 * @author ct
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})//作用于参数或方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemServiceLog {
	String description() default "";
}

 

第二步:编写切点类

package com.ctlovedove.log.aspect;

import java.lang.reflect.Method;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.json.JSONArray;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ctlovedove.joke.bean.Manager;
import com.ctlovedove.joke.bean.SystemLog;
import com.ctlovedove.joke.service.SystemLogService;
import com.ctlovedove.log.annotation.SystemControllerLog;
import com.ctlovedove.log.annotation.SystemServiceLog;
import com.ctlovedove.util.IpUtil;

/**
 * 日志管理切点类
 * @author ct
 *
 */
@Aspect
@Component
public class SystemLogAspect {
	//注入Service用于把日志保存数据库 
	@Resource
	private SystemLogService systemLogService;
	//本地异常日志记录对象  
    private  static  final Logger logger = Logger.getLogger(SystemLogAspect.class);
    
    //controller层切入点
    @Pointcut("@annotation(com.ctlovedove.log.annotation.SystemControllerLog)")
    public void controllerAspect() {
    	System.out.println("========controllerAspect===========");
    }
    //service层切入点
    @Pointcut("@annotation(com.ctlovedove.log.annotation.SystemServiceLog)")
    public void serviceAspect() {
    	System.out.println("========serviceAspect===========");
    }
	
    /**
     * 前置通知 用于拦截Controller层操作 
     * @param joinPoint 切点
     */
    @Before("controllerAspect()")
	public void doBefore(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		// 获取登陆用户信息
		Manager manager = (Manager) request.getSession().getAttribute(
				"currentManager");
		// 获取请求ip
		String ip = IpUtil.getClientIp(request);
		try {
			// *========控制台输出=========*//
			System.out.println("=====前置通知开始=====");
			System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "."
							+ joinPoint.getSignature().getName() + "()"));
			System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));
			System.out.println("请求人:" + manager.getAccountName());
			System.out.println("请求IP:" + ip);
			// *========数据库日志=========*//
			SystemLog log = new SystemLog();
			log.setDescription(getControllerMethodDescription(joinPoint));
			log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
			log.setType(0);
			log.setIp(ip);
			log.setExceptionCode(null);
			log.setExceptionDetail(null);
			log.setParams(null);
			log.setCreateUser(manager.getAccountName());
			log.setCreateDate(new Date());
			// 保存数据库
			systemLogService.save(log);
			System.out.println("=====前置通知结束=====");
		} catch (Exception e) {
			// 记录本地异常日志
			logger.error("==前置通知异常==");
			logger.error("异常信息:{}", e);
		}
	}
    
    /**
     * 异常通知 用于拦截service层记录异常日志
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut="serviceAspect()", throwing="e")
	public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		// 获取登陆用户信息
		Manager manager = (Manager) request.getSession().getAttribute(
				"currentManager");
		// 获取请求ip
		String ip = IpUtil.getClientIp(request);
		// 获取用户请求方法的参数并序列化为JSON格式字符串
		String params = "";
		Object[] args = joinPoint.getArgs();
		if (args != null) {
			JSONArray jsonArray = new JSONArray();
			jsonArray.put(args);
			params = jsonArray.toString();
		}
		try {
			/* ========控制台输出========= */
			System.out.println("=====异常通知开始=====");
			System.out.println("异常代码:" + e.getClass().getName());
			System.out.println("异常信息:" + e.getMessage());
			System.out.println("异常方法:"
					+ (joinPoint.getTarget().getClass().getName() + "."
							+ joinPoint.getSignature().getName() + "()"));
			System.out.println("方法描述:" + getServiceMthodDescription(joinPoint));
			System.out.println("请求人:" + manager.getAccountName());
			System.out.println("请求IP:" + ip);
			System.out.println("请求参数:" + params);
			/* ==========数据库日志========= */
			SystemLog log = new SystemLog();
			log.setDescription(getServiceMthodDescription(joinPoint));
			log.setExceptionCode(e.getClass().getName());
			log.setType(1);
			log.setExceptionDetail(e.getMessage());
			log.setMethod((joinPoint.getTarget().getClass().getName() + "."
					+ joinPoint.getSignature().getName() + "()"));
			log.setParams(params);
			log.setCreateUser(manager.getAccountName());
			log.setCreateDate(new Date());
			log.setIp(ip);
			// 保存数据库
			systemLogService.save(log);
			System.out.println("=====异常通知结束=====");
		} catch (Exception ex) {
			// 记录本地异常日志
			logger.error("==异常通知异常==");
			logger.error("异常信息:{}", ex);
		}

	}

    /**
     * 获取注解中对方法的描述信息 用于Controller层注解 
     * @param joinPoint 切点 
     * @return 方法描述 
     * @throws Exception 
     */
    public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception{
    	//获取目标类名
    	String targetName = joinPoint.getTarget().getClass().getName();
    	//获取方法名
    	String methodName = joinPoint.getSignature().getName();
    	//获取相关参数
    	Object[] arguments = joinPoint.getArgs();
    	//生成类对象
    	Class targetClass = Class.forName(targetName);
    	//获取该类中的方法
    	Method[] methods = targetClass.getMethods();
    	
    	String description = "";
    	
    	for(Method method : methods) {
    		if(!method.getName().equals(methodName)) {
    			continue;
    		}
    		Class[] clazzs = method.getParameterTypes();
    		if(clazzs.length != arguments.length) {
    			continue;
    		}
    		description = method.getAnnotation(SystemControllerLog.class).description();
    	}
    	return description;
    }
    
    /**
     * 获取注解中对方法的描述信息 用于service层注解
     * @param joinPoint 切点 
     * @return 方法描述 
     * @throws Exception 
     */
    public static String getServiceMthodDescription(JoinPoint joinPoint) throws Exception{
    	//获取目标类名
    	String targetName = joinPoint.getTarget().getClass().getName();
    	//获取方法名
    	String methodName = joinPoint.getSignature().getName();
    	//获取相关参数
    	Object[] arguments = joinPoint.getArgs();
    	//生成类对象
    	Class targetClass = Class.forName(targetName);
    	//获取该类中的方法
    	Method[] methods = targetClass.getMethods();
    	
    	String description = "";
    	
    	for(Method method : methods) {
    		if(!method.getName().equals(methodName)) {
    			continue;
    		}
    		Class[] clazzs = method.getParameterTypes();
    		if(clazzs.length != arguments.length) {
    			continue;
    		}
    		description = method.getAnnotation(SystemServiceLog.class).description();
    	}
    	return description;
    }
}

 

第三步:将controller的代理权交给cglib。那么此时需要在spring的配置文件中添加如下代码:

<!--启动对@AspectJ注解的支持 , proxy-target-class设置为true表示通知spring使用cglib而不是jdk的来生成代理方法,这样AOP可以拦截到Controller -->
<aop:aspectj-autoproxy proxy-target-class="true" />

 切记,如果你使用的是spring mvc的话,这句一定要写在springmvc的配置文件中,否则会似的@AspectJ不起作用的,我是深受其害的一位。

 

第四步:开始使用注解

在controller或service的方法上添加注解,示例如下:

@RequestMapping("save")
@SystemControllerLog(description="新增笑话")
public String save(JokeInfo jokeInfo, RedirectAttributes attributes, HttpServletRequest request, HttpSession session){
	logger.info("新增笑话--jokeinfo--"+jokeInfo);
	try {
		if(jokeInfo == null){
			attributes.addFlashAttribute("errorMsg", "新增笑话失败");
			return "redirect:list.do";
		}
		if(StringUtil.isNull(jokeInfo.getSource())){
			jokeInfo.setSource(session.getAttribute("currentManager")+"");
		}
		jokeInfo.setSourceIp(IpUtil.getClientIp(request));
		jokeInfo.setPubDate(new Date());
		jokeInfoService.save(jokeInfo);
		attributes.addFlashAttribute("errorMsg", "新增成功");
	} catch (Exception e) {
		logger.error("保存新笑话失败", e);
		attributes.addFlashAttribute("errorMsg", "新增笑话失败");
	}
	return "redirect:list.do";
}

 

最终效果可见下面截图:



 如果操作顺利的话,以上便是完整的步骤了。但是在我的编写与测试过程中,遇到了好多问题,例如:

 

问题1:在启动tomcat的时候,报org.xml.sax.SAXParseException; lineNumber: 23; columnNumber: 53; 元素 "aop:aspectj-autoproxy" 的前缀 "aop" 未绑定

 

通过查询文档发现,在springmvc配置文件中,我们不仅仅要引入Aop的名称空间,还要在xsi:schemaLocation中加入aop的xsd文件 。

 

问题2:AspectJ 出现错误::0 can't find referenced pointcut

原因是我用的jdk7与aspectjrt.jar包不兼容,解决方法是更换jar包。

当环境为:

jdk 1.7, spring version is 3.0+, 如果使用aspectjrt-1.6.2 and aspectjweaver-1.6.2这个版本,就会出现上述错误,将aspectj and aspectjweaver 版本改为1.7.3 or more,问题得到解决。

 

补充:上面是基于注解的方式进行的aop配置,但有些朋友更喜欢使用xml配置文件的方式,比如我,所以下面是部分xml的配置,如有问题,还请大神们指教。

1、首先,将切面类中的SystemLogAspect中的注解去掉。

package com.ctlovedove.log.aspect;

import java.lang.reflect.Method;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.json.JSONArray;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ctlovedove.joke.bean.Manager;
import com.ctlovedove.joke.bean.SystemLog;
import com.ctlovedove.joke.service.SystemLogService;
import com.ctlovedove.log.annotation.SystemControllerLog;
import com.ctlovedove.log.annotation.SystemServiceLog;
import com.ctlovedove.util.IpUtil;

/**
 * 日志管理切点类
 * @author chenting
 *
 */
public class SystemLogAspect {
	//注入Service用于把日志保存数据库 
	@Resource
	private SystemLogService systemLogService;
	//本地异常日志记录对象  
    private  static  final Logger logger = Logger.getLogger(SystemLogAspect.class);
    
   
    /**
     * 前置通知 用于拦截Controller层操作 
     * @param joinPoint 切点
     */
	public void doBefore(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		// 获取登陆用户信息
		Manager manager = (Manager) request.getSession().getAttribute(
				"currentManager");
		// 获取请求ip
		String ip = IpUtil.getClientIp(request);
		try {
			// *========控制台输出=========*//
			System.out.println("=====前置通知开始=====");
			System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "."
							+ joinPoint.getSignature().getName() + "()"));
			System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));
			System.out.println("请求人:" + manager.getAccountName());
			System.out.println("请求IP:" + ip);
			// *========数据库日志=========*//
			SystemLog log = new SystemLog();
			log.setDescription(getControllerMethodDescription(joinPoint));
			log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
			log.setType(0);
			log.setIp(ip);
			log.setExceptionCode(null);
			log.setExceptionDetail(null);
			log.setParams(null);
			log.setCreateUser(manager.getAccountName());
			log.setCreateDate(new Date());
			// 保存数据库
			systemLogService.save(log);
			System.out.println("=====前置通知结束=====");
		} catch (Exception e) {
			// 记录本地异常日志
			logger.error("==前置通知异常==");
			logger.error("异常信息:{}", e);
		}
	}
    
    /**
     * 异常通知 用于拦截service层记录异常日志
     * @param joinPoint
     * @param e
     */
	public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		// 获取登陆用户信息
		Manager manager = (Manager) request.getSession().getAttribute(
				"currentManager");
		// 获取请求ip
		String ip = IpUtil.getClientIp(request);
		// 获取用户请求方法的参数并序列化为JSON格式字符串
		String params = "";
		Object[] args = joinPoint.getArgs();
		if (args != null) {
			JSONArray jsonArray = new JSONArray();
			jsonArray.put(args);
			params = jsonArray.toString();
		}
		try {
			/* ========控制台输出========= */
			System.out.println("=====异常通知开始=====");
			System.out.println("异常代码:" + e.getClass().getName());
			System.out.println("异常信息:" + e.getMessage());
			System.out.println("异常方法:"
					+ (joinPoint.getTarget().getClass().getName() + "."
							+ joinPoint.getSignature().getName() + "()"));
			System.out.println("方法描述:" + getServiceMthodDescription(joinPoint));
			System.out.println("请求人:" + manager.getAccountName());
			System.out.println("请求IP:" + ip);
			System.out.println("请求参数:" + params);
			/* ==========数据库日志========= */
			SystemLog log = new SystemLog();
			log.setDescription(getServiceMthodDescription(joinPoint));
			log.setExceptionCode(e.getClass().getName());
			log.setType(1);
			log.setExceptionDetail(e.getMessage());
			log.setMethod((joinPoint.getTarget().getClass().getName() + "."
					+ joinPoint.getSignature().getName() + "()"));
			log.setParams(params);
			log.setCreateUser(manager.getAccountName());
			log.setCreateDate(new Date());
			log.setIp(ip);
			// 保存数据库
			systemLogService.save(log);
			System.out.println("=====异常通知结束=====");
		} catch (Exception ex) {
			// 记录本地异常日志
			logger.error("==异常通知异常==");
			logger.error("异常信息:{}", ex);
		}

	}

    /**
     * 获取注解中对方法的描述信息 用于Controller层注解 
     * @param joinPoint 切点 
     * @return 方法描述 
     * @throws Exception 
     */
    public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception{
    	//获取目标类名
    	String targetName = joinPoint.getTarget().getClass().getName();
    	//获取方法名
    	String methodName = joinPoint.getSignature().getName();
    	//获取相关参数
    	Object[] arguments = joinPoint.getArgs();
    	//生成类对象
    	Class targetClass = Class.forName(targetName);
    	//获取该类中的方法
    	Method[] methods = targetClass.getMethods();
    	
    	String description = "";
    	
    	for(Method method : methods) {
    		if(!method.getName().equals(methodName)) {
    			continue;
    		}
    		Class[] clazzs = method.getParameterTypes();
    		if(clazzs.length != arguments.length) {//比较方法中参数个数与从切点中获取的参数个数是否相同,原因是方法可以重载哦
    			continue;
    		}
    		description = method.getAnnotation(SystemControllerLog.class).description();
    	}
    	return description;
    }
    
    /**
     * 获取注解中对方法的描述信息 用于service层注解
     * @param joinPoint 切点 
     * @return 方法描述 
     * @throws Exception 
     */
    public static String getServiceMthodDescription(JoinPoint joinPoint) throws Exception{
    	//获取目标类名
    	String targetName = joinPoint.getTarget().getClass().getName();
    	//获取方法名
    	String methodName = joinPoint.getSignature().getName();
    	//获取相关参数
    	Object[] arguments = joinPoint.getArgs();
    	//生成类对象
    	Class targetClass = Class.forName(targetName);
    	//获取该类中的方法
    	Method[] methods = targetClass.getMethods();
    	
    	String description = "";
    	
    	for(Method method : methods) {
    		if(!method.getName().equals(methodName)) {
    			continue;
    		}
    		Class[] clazzs = method.getParameterTypes();
    		if(clazzs.length != arguments.length) {//比较方法中参数个数与从切点中获取的参数个数是否相同,原因是方法可以重载哦
    			continue;
    		}
    		description = method.getAnnotation(SystemServiceLog.class).description();
    	}
    	return description;
    }
}

 2、xml配置文件代码如下(该配置仍然要方在springmvc的配置文件中,因为仍然有部分使用了注解)

<!-- 系统操作日志配置  start -->
	<!-- 声明切面类 -->
	<bean id="SystemLogAspect" class="com.ctlovedove.log.aspect.SystemLogAspect"></bean>
	<aop:config>
		<!-- 声明切面 -->
		<aop:aspect ref="SystemLogAspect">
			<!-- 
				1、pointcut="@annotation(com.ctlovedove.log.annotation.SystemControllerLog)" 表示切入点是注解 
				2、method 指向的方法,是切面类中的方法,表示当程序触发pointcut指向的注解时,aop会启动method方法
			-->
			<aop:before method="doBefore" pointcut="@annotation(com.ctlovedove.log.annotation.SystemControllerLog)"/>
			<!-- <aop:after method="doAfterThrowing" pointcut="@annotation(com.ctlovedove.log.annotation.SystemServiceLog)"/> -->
			<aop:after-throwing method="doAfterThrowing" pointcut="@annotation(com.ctlovedove.log.annotation.SystemServiceLog)" throwing="e"/>
		</aop:aspect>
	</aop:config>
	<!-- 系统操作日志配置  end -->

 

其他的还跟上面的方式一样。这样同样可以正常使用,谢谢。

  • 大小: 45.2 KB
分享到:
评论

相关推荐

    spring MVC AOP注解方式如何拦截controller 例子

    有人问 Sping AOP用AspectJ注解的方式拦截不到SpringMVC的controller方法? 我这里提供了一种解决方法,仅供参考

    spring2.5.chm帮助文档(中文版)

    Spring Framework 开发参考手册 目录 1. 简介 1.1. 概览 1.1.1. 使用场景 2. Spring 2.0和 2.5的新特性 ...2.5.1. Spring MVC合理的默认值 2.5.2. Portlet 框架 2.5.3. 基于Annotation的控制器 ......

    25个经典的Spring面试问答

    配置与注解:理解Spring的XML配置和注解配置,并能够在这两种配置方式中进行选择。 Spring AOP与AspectJ:理解Spring AOP的概念,以及如何使用AspectJ实现AOP。 Spring与其它技术集成:了解Spring与其它技术的集成,...

    spring杂谈 作者zhang KaiTao

    1.6 »Spring 之AOP AspectJ切入点语法详解(最全了,不需要再去其他地找了) 1.7 Spring开闭原则的表现-BeanPostProcessor扩展点-2 1.8 Spring3.1 对Bean Validation规范的新支持(方法级别验证) 1.9 Spring对事务...

    spring_MVC源码

    弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件。本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mvc和rest小例子没有介绍到数据层的内容,...

    Spring+3.x企业应用开发实战光盘源码(全)

     第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、使用注解进行配置等内容。  第8章:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等...

    Spring中文帮助文档

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring 2.0 开发参考手册

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...

    Spring API

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring.3.x企业应用开发实战(完整版).part2

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...

    spring chm文档

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    Spring3.x企业应用开发实战(完整版) part1

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...

    陈开雄 Spring+3.x企业应用开发实战光盘源码.zip

     第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、使用注解进行配置等内容。  第8章:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等...

    Spring in Action(第二版 中文高清版).part2

    第一部分 Spring的核心 第1章 开始Spring之旅 1.1 Spring是什么 1.2 开始Spring之旅 1.3 理解依赖注入 1.3.1 依赖注入 1.3.2 DI应用 1.3.3 企业级应用中的依赖注入 1.4 应用AOP 1.4.1 AOP介绍 1.4.2 AOP...

    Spring in Action(第二版 中文高清版).part1

    第一部分 Spring的核心 第1章 开始Spring之旅 1.1 Spring是什么 1.2 开始Spring之旅 1.3 理解依赖注入 1.3.1 依赖注入 1.3.2 DI应用 1.3.3 企业级应用中的依赖注入 1.4 应用AOP 1.4.1 AOP介绍 1.4.2 AOP...

    Spring攻略(第二版 中文高清版).part1

    第3章 Spring AOP和AspectJ支持 112 3.1 启用Spring的AspectJ注解支持 113 3.1.1 问题 113 3.1.2 解决方案 113 3.1.3 工作原理 113 3.2 用AspectJ注解声明aspect 115 3.2.1 问题 115 3.2.2 解决方案...

    Spring攻略(第二版 中文高清版).part2

    第3章 Spring AOP和AspectJ支持 112 3.1 启用Spring的AspectJ注解支持 113 3.1.1 问题 113 3.1.2 解决方案 113 3.1.3 工作原理 113 3.2 用AspectJ注解声明aspect 115 3.2.1 问题 115 3.2.2 解决方案...

    doodle:A Simple Java MVC Framework。提供Bean容器、Ioc、Aop、MVC功能

    doodle是一个简易的Java MVC框架,它提供了类似于spring 的Bean容器、IOC、AOP、MVC等功能 代码简洁、轻量,适合用于参考学习spring 一行代码即可启动服务,内置Tomcat容器 DispatcherServlet请求逻辑处理采用责任链...

    S-mall-ssm:小小商城系统,JavaWEB项目,基于SSM,仿天猫页面,功能齐全,实现了自动处理关联查询的通用Mapper、抽象 BaseService 类、注解鉴权、参数注解校验等

    小小商城系统 - SSM版 练手 JavaWEB 项目,本版本为SSM版。本项目实现了通用 Mapper,免写 SQL,全自动处理关联查询。...本项目为 Maven 项目,后端使用 Spring 4 + SpringMVC 4 + Mybatis 3.4 + aspectj 1.8

Global site tag (gtag.js) - Google Analytics