使用spring的大神们都知道,spring支持声名式事物,但在特定的场景下,声名式事物是失效的。
spring的声名式事物是通过aop事项的。以jdk的动态代理实现为例。
1.定义接口person
/** * 〈一句话功能简述〉<br> * 〈〉 * * @author Administrator * @create 2019/2/21 * @since 1.0.0 */ public interface Person { void giveMoney(); void submit(); }
2.Handler
/** * 〈一句话功能简述〉<br> * 〈〉 * * @author Administrator * @create 2019/2/21 * @since 1.0.0 */ public class Handler implements InvocationHandler { private Person person; @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("giveMoney")){ System.out.println("call giveMoney"); }else if(method.getName().equals("submit")){ System.out.println("call submit"); } return method.invoke(person,args); } public Handler(Person person) { this.person = person; } } 在handler中对person的两个方法giveMoney和submit添加了打印信息。
3.student实现类
/** * 〈一句话功能简述〉<br> * 〈〉 * * @author Administrator * @create 2019/2/21 * @since 1.0.0 */ public class Student implements Person { private String name; public Student(String name) { this.name = name; } public void giveMoney() { System.out.println(name + "上交班费50元"); submit(); } @Override public void submit() { System.out.println("submit"); } public static void main(String[] args) { Person zhangsan = new Student("张三"); InvocationHandler stuHandler = new Handler(zhangsan); Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler); stuProxy.giveMoney(); stuProxy.submit(); } }
运行结果:
call giveMoney
张三上交班费50元
submit
call submit
submit
从运行结果中看出,调用代理类的giveMoney()方法,打印结果为
call giveMoney
张三上交班费50元
submit
并没有打印出 call submit。
单独调用代理类的submit()方法,打印出了
call submit
submit
所以,在同一个类中,有方法a和b,这时如果在方法a中调用方法b,即使在b方法上添加了事物声明也是不生效的。
在不同类中调用b方法是生效的。