spring 两大特性ioc和aop,ioc使用注解来说很简单这里不做详细介绍,这里主要介绍spring aop的使用。
进行spring编程之前需要了解aop的几个概念与名词。
切面(Aspect)
连接点(Joinpoint)
通知(Advice)
切入点(Pointcut)等等 。。
进行spring编程之前需要了解aop的几个概念与名词。
通俗的讲,切面就是要插入程序中与具体业务无关的操作,比如日志记录,事务管理。有了切面,就得匹配切面插入的位置,也就是pointcut。至于连接点就是切面与业务程序的交互对象,从这个对象可以拿到业务的一些信息,比如调用的方法,对象等。。
其他不说,直接上代码,根据代码来理解。
首先说下jar包,spring2.5是在spring的包里面包含了所有的aop的包,之后版本没有了。
使用AspectJ注解开发AOP应用时,会遇到以下问题: ::0 can't find referenced pointcut 这个问题,实际是与你所在的开发环境有关,如下表
jdk version | spring version | aspectjrt version and aspectjweaver version |
1.6 | 3.0 + | aspectjrt-1.6.2 and aspectjweaver-1.6.2 |
1.7 | 3.0 + | aspectjrt-1.7.3 and aspectjweaver-1.7.3 |
测试demo里面还包含其他的jar包这里不意义描述了,具体的jar包可以下载demo
下面直接晒例子了:
定义切面接口和业务接口
package com.service;
public interface ILoginService {
public boolean login(String name,String password);
}
package com.service;
import org.aspectj.lang.JoinPoint;
public interface ILogService {
public void log();
public void logArg(JoinPoint point);
public void logArgAndReturn(JoinPoint point, Object returnObj);
}
定义具体实现类
package com.service;
import org.springframework.stereotype.Service;
@Service
public class LoginServiceImpl implements ILoginService {
public boolean login(String name,String password) {
StringBuffer sb = new StringBuffer();
sb.append("Target:").append("login:").append(name).append(",").append(password);
System.out.println(sb.toString());
return true;
}
}
package com.service;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogServiceImpl implements ILogService {
/*
* 不带参数和返回值
*/
@Before(value="execution(* com.service.*Impl.*(..))")
public void log() {
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " *******Log的aop*********");
}
/*
* 带参数
*/
@Before(value="execution(* com.service.*Impl.*(..))")
public void logArg(JoinPoint point) {
StringBuffer sb = new StringBuffer();
// 获取连接点所在的目标对象
Object obj = point.getTarget();
// 获取连接点的方法签名对象
String method = point.getSignature().getName();
// 获取连接点方法运行时的入参列表
Object[] args = point.getArgs();
sb.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append(" ");
sb.append(obj.toString().substring(0, obj.toString().indexOf('@')));
sb.append(".").append(method).append(" ");
sb.append("Args:[");
if (args != null) {
for (int i = 0; i < args.length; i++) {
Object o = args[i];
sb.append(o);
if (i < args.length - 1) {
sb.append(",");
}
}
}
sb.append("]");
System.out.println(sb.toString());
}
/**
*
* <p>
* 功能实现描述:有参并有返回值的方法
*
*/
@AfterReturning(value="execution(* com.service.*Impl.*(..))",returning="returnObj")
public void logArgAndReturn(JoinPoint point, Object returnObj) {
StringBuffer sb = new StringBuffer();
// 获取连接点所在的目标对象
Object obj = point.getTarget();
// 获取连接点的方法签名对象
String method = point.getSignature().getName();
// 获取连接点方法运行时的入参列表
Object[] args = point.getArgs();
sb.append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).append(" ");
sb.append(obj.toString().substring(0, obj.toString().indexOf('@')));
sb.append(".").append(method).append(" ");
sb.append("Args:[");
if (args != null) {
for (int i = 0; i < args.length; i++) {
Object o = args[i];
sb.append(o);
if (i < args.length - 1) {
sb.append(",");
}
}
}
sb.append("]").append(" ");
sb.append("Ret:[").append(returnObj).append("]");
System.out.println(sb.toString());
}
}
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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
">
<!-- 使用代理 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 采用注解的方式配置bean -->
<context:annotation-config />
<!-- 配置要扫描的包 -->
<context:component-scan base-package="com.service" />
<!-- 根据不同的运行环境加载配置文件 -->
<context:property-placeholder location="classpath:config.properties" />
<!-- 使用aop注解 -->
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
<!-- <import resource="classpath:spring-mybatis.xml" />
<import resource="classpath:spring-redis.xml" /> -->
</beans>
ok 一切都完了 下面提供一个juin的测试例子(spring junit)
package com.test;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.service.ILoginService;
public class testAop {
@Autowired
ILoginService login;
@Test
public void testLogin(){
ApplicationContext context = new
ClassPathXmlApplicationContext("classpath*:spring-context.xml");
login =context.getBean(ILoginService.class);
login.login("测试","123456");
}
}
控制台结果为:
2015-12-04 15:47:35 *******Log的aop*********
2015-12-04 15:47:35 com.service.LoginServiceImpl.login Args:[测试,123456]
Target:login:测试,123456
2015-12-04 15:47:35 com.service.LoginServiceImpl.login Args:[测试,123456] Ret:[true]
大工搞成,突然发现不能上传附件。。。。
已经上传资源 http://download.csdn.net/detail/u013666974/9326415