目录
2.aop的自定义通知和配置(before,after,afterReturning,afterThrowing,around)
1.spring中的动态代理
UserService.java:
package com.sikiedu.service;
public interface UserService {
void save();
void delete();
void update();
void find();
}
UserServicelmpl.java:
package com.sikiedu.service;
public class UserServicelmpl implements UserService {
@Override
public void save() {
System.out.println("save");
}
@Override
public void delete() {
System.out.println("delete");
}
@Override
public void update() {
System.out.println("update");
}
@Override
public void find() {
System.out.println("find");
}
}
UserServiceProxy.java:
package com.sikiedu.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.sikiedu.service.UserService;
import com.sikiedu.service.UserServicelmpl;
public class UserServiceProxy {
public UserService getUserServiceProxy(UserService us){
return (UserService)Proxy.newProxyInstance(UserService.class.getClassLoader(),
UserServicelmpl.class.getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
Object invoke=method.invoke(us, args);
System.out.println("提交/回滚");
return invoke;
}
});
}
}
AopTest.java:
package com.sikiedu.test;
import org.junit.Test;
import com.sikiedu.service.UserService;
import com.sikiedu.service.UserServicelmpl;
public class AopTest {
@Test
public void Test(){
UserServiceProxy usProxy=new UserServiceProxy();
UserService us=new UserServicelmpl();
UserService us_PowerUp= usProxy.getUserServiceProxy(us);
us_PowerUp.find();
}
}
运行结果:
2.aop的自定义通知和配置(before,after,afterReturning,afterThrowing,around)
导入包:
导入aop约束:
新建applicationContext.xml,并右键点击:【openwith】-【other...】-【spring config editor】-【namespace】-【勾选aop,beans】
然后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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
</beans>
MyAdvice.java:
package ssm.sikiedu.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAdvice {
//before 前置通知 在目标方法前调用
public void before(){
System.out.println("before");
}
//after 最终通知(后置通知) 在目标方法后调用,无论是否出现异常都会执行 类似finally
public void after(){
System.out.println("after");
}
//afterReturning 成功通知(后置通知) 在目标方法执行后,并且执行成功才调用,如果方法出现异常则不调用
public void afterReturning(){
System.out.println("afterReturning");
}
//afterThrowing 异常通知(后置通知) 在目标方法执行出现异常的时候才会调用
public void afterThrowing(){
System.out.println("afterThrowing");
}
//环绕通知
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("around before");
Object proceed = pjp.proceed();
System.out.println("around after");
return proceed;
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 目标对象 -->
<bean name="userService" class="com.sikiedu.service.UserServicelmpl"></bean>
<!-- 通知对象 -->
<bean name="myAdvice" class="ssm.sikiedu.aop.MyAdvice"></bean>
<aop:config>
<!-- 切入点 expression切入点表达式 可以配置要增强的方法 -->
<!-- *com.sikiedu.service.*Servicelmpl.*(..) -->
<!-- public void com.sikiedu.service.UserServicelmpl.save() -->
<!-- id就是唯一标识 -->
<aop:pointcut id="servicePc" expression="execution(public void com.sikiedu.service.UserServicelmpl.save())"/>
<!-- 切面 通知+切入点 -->
<aop:aspect ref="myAdvice">
<!-- 通知类型 -->
<aop:before method="before" pointcut-ref="servicePc"/>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="servicePc"/>
<!-- 成功通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="servicePc"/>
<!-- 异常通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="servicePc"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="servicePc"/>
</aop:aspect>
</aop:config>
</beans>
AopTest.java:
package com.sikiedu.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sikiedu.service.UserService;
import com.sikiedu.service.UserServicelmpl;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name="userService")
UserService us;
@Test
public void Test2(){
us.delete();
}
}
运行结果:(下面是正常运行的结果,但是我并没有运行成功)