注解配置
第一步:创建一个Java项目
第二步:编写业务类
package cn.zj.spring.service.impl;
import org.springframework.stereotype.Service;
import cn.zj.spring.pojo.User;
@Service
public class UserServiceImpl {
public void insert(User user) {
System.out.println("执行dao的层 insert方法");
}
public void updateByPrimaryKey(User user) {
System.out.println("执行dao的层 update方法");
}
}
第三步:编写模拟事务管理器
package cn.zj.spring.utils;
import java.util.Arrays;
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.AfterThrowing;
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.springframework.stereotype.Component;
/*
* 此类模拟事务管理器(专门处理事务的类)
*
*
*
* @Aspect
* 把当前类作为AOP的切面配置类
* -----------------------
* @Pointcut
* 编写切入点语法的注解
*/
@Component
@Aspect //相当于 <aop:aspect ref="MyTxManager">
public class TransactionManagerHandler {
/*
* 创建能够编写切入点语法的方法
*
*/
//相当于 : <aop:pointcut expression="execution(* cn.zj.spring.service..*.*(..))" id="pt"/>
@Pointcut("execution(* cn.zj.spring.service..*.*(..))")
public void myPoint() {}
//@Before("myPoint()") //相当于 :<aop:before method="begin" pointcut-ref="pt"/>
public void begin(JoinPoint jp) {
System.out.println("连接点:"+jp);
System.out.println("args :"+Arrays.toString(jp.getArgs()));
System.out.println("开启事务=");
}
//@AfterReturning("myPoint()")//相当于:<aop:after-returning method="commit" pointcut-ref="pt"/>
public void commit() {
System.out.println("提交事务=============");
}
//@AfterThrowing(value = "myPoint()",throwing = "ex")//相当于:<aop:after-throwing method="rollback" throwing="ex" pointcut-ref="pt"/>
public void rollback(Throwable ex) {
System.out.println("ex :"+ex.getMessage());
System.out.println("回滚事务===========");
}
//@After("myPoint()")//相当于:<aop:after method="close" pointcut-ref="pt"/>
public void close() {
System.out.println("释放资源==============");
}
//----------------------------------------------------
@Around("execution(* cn.zj.spring.service..*.*(..))")//相当于:<aop:around method="allInOne" pointcut-ref="pt"/>
public void allInOne(ProceedingJoinPoint jp) {
try {
System.out.println("开启事务----------------");
//执行真实对象的方法
jp.proceed();
System.out.println("提交事务-----------------");
} catch (Throwable e) {
System.out.println("回滚事务-------------------");
}finally {
System.out.println("释放资源------------------");
}
}
}
第四步:编写applicationContext.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"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<context:component-scan base-package="cn.zj.spring"/>
<!-- 开启AOP的注解配置 -->
<aop:aspectj-autoproxy/>
</beans>
第五步:编写测试代码
package cn.zj.spring.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.zj.spring.pojo.User;
import cn.zj.spring.service.UserService;
import cn.zj.spring.service.impl.UserServiceImpl;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserServiceTest {
@Autowired
private UserServiceImpl userService;
@Test
public void testInsert() {
User user = new User(null, "钢铁侠", "gtx@qq.com");
System.out.println(userService.getClass().getName());
//有接口 : com.sun.proxy.$Proxy13
//没有接口 :cn.zj.spring.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$ea3c2726
userService.insert(user);
}
@Test
public void testUpdateByPrimaryKey() {
User user = new User(2, "蜘蛛侠", "zhizhuxia@qq.com");
userService.updateByPrimaryKey(user);
}
@Test
public void testName() throws Exception {
userService.toString();
}
}
纯注解配置
package cn.zj.spring.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan("cn.zj.spring")
@EnableAspectJAutoProxy //开启aop注解配置
public class SpringConfig {
}
AOP注解说明
@Aspect作用:
把当前类声明为切面类。
@Before
作用:
把当前方法看成是前置通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@AfterReturning
作用:
把当前方法看成是最终通知。报异常,就不执行
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@AfterThrowing
作用:
把当前方法看成是异常通知。只有报异常才执行
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@After
作用:
把当前方法看成是后置通知。不管报不报异常都执行
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@Around
作用:
把当前方法看成是环绕通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@Pointcut
作用:
指定切入点表达式
属性:
value:指定表达式的内容