业务层实现类java
@Service("xxxService")
注入对象spring
@Autowired
注解扫描.net
<context:component-scan base-package="cn.itcast" />
通知类上代理
[@Aspect](https://my.oschina.net/aspect) @Component("myAspect")//将通知类交给spring管理
开启Aspectj注解自动代理机制code
<aop:aspectj-autoproxy />
前置通知component
public void before(JoinPoint joinPoint){ //判断某用户可执行的方法中,是否存在要运行的方法 if("method1".equals(joinPoint.getSignature().getName())){ throw new RuntimeException("没有权限执行该方法"); } }
后置通知xml
public void afterReturing(JoinPoint joinPoint, Object returnVal){ //加强 }
环绕通知对象
public Object around(ProceedingJoinPoint proceedJoinPoint) throws Throwable{ //目标方法的执行 Object object = proceedJoinPoint.proceed(); return object; }
环绕通知-终极版接口
public Object around(ProceedingJoinPoint proceedingJoinPoint){ try{ //前置通知 Object result = proceedingJoinPoint.proceed(); //后置通知 }catch(Exception e){ //抛出通知 }finally{ //最终通知 return Object } }
抛出通知开发
public void afterThrowing(JoinPoint joinPoint, Throwable ex){ System.out.println(joinPoint.getTarget().getClass().getSimpleName()+" : "+joinPoint.getSignature().getName()+" : "+ex.getMessage()); }
最终通知
public void after(JoinPoint joinPoint){ System.out.println(joinPoint.toLongString()); }
##3. 配置切点切面 ##
通知方法上
@Before("value="execution(* cn.itcast.spring..*.*(..))") @AfterReturning("value="execution(* cn.itcast.spring..*.*(..))") @Around("value="execution(* cn.itcast.spring..*.*(..))") @AfterThrowing("value="execution(* cn.itcast.spring..*.*(..))") @After("value="execution(* cn.itcast.spring..*.*(..))") @DeclareParents//引介通知
问题:若是直接在通知注解中写切入点表达式,会发生重复编写,后期不便于维护
解决:
在实际开发中,切入点都是单独定义维护的,如:
1.使用xml定义切入点aop:pointcut
2.使用注解单独定义切入点@Pointcut
@Pointcut("value="execution(* cn.itcast.spring..*.*(..))") private void myPointcut(){ } @Before(value="myPointcut()")
java.lang.ClassCastException:com.sun.proxy.$Proxy17 cannot be cast to xxxServiceImpl
缘由:使用了jdk动态代理,目标对象是接口,没法转换为子类
解决方法: 使用类代理(cglib动态代理)
注解:
<aop:aspect-autoproxy proxy-target-class="true" />
xml
<aop:config proxy-target-class="true">