1.建立项目
2.导包
Spring的包
增长:
aopalliance
aspectjweaver
3.建立Dao层接口及实现层
4.建立通知类及要执行的通知方法
5.配置ApplicationContext.xml
配置bean
配置AOP aop:config
配置切点 aop:pointcut
id
expression "execution(针对的方法)"
配置切面 aop:aspect
id
ref
配置链接点
aop:before
aop:after
aop:after-returning
aop:around
aop:after-throwing
6.写测试类html
1.建立项目SpringAop1java
2.导入须要的包spring
3.建立Dao层接口IUserDaoexpress
package com.hp.dao; public interface IUserDao { int login(String name,String password); int div(int a,int b); }
建立Dao层实现UserDaoImplide
package com.hp.dao.impl; import com.hp.dao.IUserDao; public class UserDaoImpl implements IUserDao { @Override public int login(String name, String password) { if("admin".equals(name) && "123".equals(password)){ System.out.println("登陆成功"); return 1; } else{ System.out.println("登陆失败"); } return 0; } @Override public int div(int a, int b) { int res=a/b; //b=0时抛出异常 return res; } }
4.建立通知类及要执行的通知方法LogAdvice测试
package com.hp.advice; import org.aspectj.lang.JoinPoint; public class LogAdvice { public void before(JoinPoint jp){ /* * 如何才能知道调用的是哪个方法 * 给before方法添加一个参数JoinPoint */ String methodName = jp.getSignature().getName(); //获取方法名 Object[] args = jp.getArgs(); //获取参数 System.out.println("前置通知"); System.out.println("将要执行:"+methodName+"方法"); System.out.println("参数列表:"); for (Object object : args) { System.out.println(object); } } public void after(JoinPoint jp){ String methodName = jp.getSignature().getName(); System.out.println(methodName + "方法执行结束"); System.out.println("后置通知"); } public void afterReturning(Object res) throws Throwable{ System.out.println("返回值:"+res); System.out.println("返回通知"); } public void afterThrowing(Exception ex){ System.out.println("异常信息:"+ex.getMessage()); System.out.println("分母不能为0"); } }
5.配置ApplicationContext.xmlspa
<?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:tx="http://www.springframework.org/schema/tx" 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/tx http://www.springframework.org/schema/tx/spring-tx.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-4.1.xsd"> <!-- 声明bean --> <bean id="IUserDao" class="com.hp.dao.impl.UserDaoImpl" ></bean> <bean id="logAdvice" class="com.hp.advice.LogAdvice"></bean> <!-- 配置AOP --> <aop:config> <!-- 配置切入点 --> <!-- 第一个*表示访问符和返回类型任意,括号里的两个点表示任意参数 --> <aop:pointcut expression="execution(* com.hp.dao.*.*(..))" id="logPoint" /> <!-- 配置切面 --> <aop:aspect id="logAspect" ref="logAdvice" > <!-- 配置链接点 --> <aop:before method="before" pointcut-ref="logPoint" /> <aop:after method="after" pointcut-ref="logPoint"/> <aop:after-returning method="afterReturning" pointcut-ref="logPoint" returning="res"/> <aop:after-throwing method="afterThrowing" pointcut-ref="logPoint" throwing="ex"/> </aop:aspect> </aop:config> </beans>
6.写测试类MainTest3d
package com.hp.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.hp.dao.IUserDao; public class MainTest { @Test public void login() throws Exception{ ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml"); IUserDao iUserDao = (IUserDao) context.getBean("IUserDao"); iUserDao.login("admin", "123"); System.out.println("-------------"); iUserDao.div(1, 0); } }7.运行结果:
前置通知 将要执行:login方法 参数列表: admin 123 登陆成功 login方法执行结束 后置通知 返回值:1 返回通知 ------------- 前置通知 将要执行:div方法 参数列表: 1 0 div方法执行结束 后置通知 异常信息:/ by zero 分母不能为08.项目结构:
1.建立项目SpringAop2code
2.导入须要的包(同上)component
3.建立Dao层接口IUserDao
package com.hp.dao; public interface IUserDao { int login(String name,String password); int div(int a,int b); }
建立Dao层实现UserDaoImpl
package com.hp.dao.impl; import org.springframework.stereotype.Repository; import com.hp.dao.IUserDao; @Repository("IUserDao") public class UserDaoImpl implements IUserDao { @Override public int login(String name, String password) { if("admin".equals(name) && "123".equals(password)){ System.out.println("登陆成功"); return 1; } else{ System.out.println("登陆失败"); } return 0; } @Override public int div(int a, int b) { int res=a/b; //b=0时抛出异常 return res; } }
4.建立通知类及要执行的通知方法LogAdvice
package com.hp.advice; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component //(把普通pojo实例化到spring容器中,至关于配置文件中的<bean id="" class=""/>) public class LogAdvice { @Pointcut("execution(* com.hp.dao.*.*(..))") private void anyMethod(){} //声明一个切入点,anyMethod为切入点名称 @Before("anyMethod()") public void before(JoinPoint jp){ /* * 如何才能知道调用的是哪个方法 * 给before方法添加一个参数JoinPoint */ String methodName = jp.getSignature().getName();//获取方法名 Object[] args = jp.getArgs();//获取参数 System.out.println("前置通知"); System.out.println("将要执行:"+methodName+"方法"); for (Object object : args) { System.out.println(object); } } @After("anyMethod()") public void after(JoinPoint jp){ String methodName = jp.getSignature().getName(); System.out.println(methodName+"方法执行结束"); System.out.println("后置通知"); } @AfterReturning(pointcut ="anyMethod()", returning="res") public void afterReturning(Object res) throws Throwable{ System.out.println("方法返回值:"+res); System.out.println("返回通知"); } @AfterThrowing(pointcut = "anyMethod()", throwing="ex") public void afterThrowing(Exception ex){ System.out.println("异常信息:"+ex.getMessage()); System.out.println("分母不能为0"); } }
5.配置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:tx="http://www.springframework.org/schema/tx" 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/tx http://www.springframework.org/schema/tx/spring-tx.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-4.1.xsd"> <!-- spring注解 --> <context:component-scan base-package="com.hp.dao,com.hp.advice" /> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
6.写测试类MainTest
package com.hp.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.hp.dao.IUserDao; public class MainTest { @Test public void login() throws Exception{ ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml"); IUserDao iUserDao = (IUserDao) context.getBean("IUserDao"); iUserDao.login("admin", "123"); System.out.println("-------------"); iUserDao.div(1, 0); } }
7.运行结果:
前置通知 将要执行:login方法 参数列表: admin 123 登陆成功 login方法执行结束 后置通知 返回值:1 返回通知 ------------- 前置通知 将要执行:div方法 参数列表: 1 0 div方法执行结束 后置通知 异常信息:/ by zero 分母不能为0
8.项目结构:
1. 在返回通知中,如何获取返回值?
xml中<aop:after-returning method="afterReturning" pointcut-ref="logPoint" returning="res"/>
Advice中传递一个Object类型的res参数
2. 在异常通知中,如何获取出现的异常?
xml:<aop:after-throwing method="afterThrowing" pointcut-ref="logPoint" throwing="ex"/>
Advice中传递一个Exception类型的ex参数
Advice中ex.getMessage()
3. 当异常出现时,返回通知和后置通知还会执行吗?
返回通知不会执行,后置通知会执行
4. 当后置通知与返回通知同时存在时,哪个先执行呢?
执行顺序按照在xml配置文件中的配置顺序执行
1. 使用注解时,须要在XML配置文件中添加<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2. @ Component注解,至关于配置文件中的,<bean >
3. @ Pointcut注解,至关于配置文件中的,<aop:pointcut>
4. @ Aspect注解,至关于配置文件中的, <aop:aspect>
5. @ Before注解,至关于配置文件中的.<aop:before> after afterrunning afterthrowing around
注:异常通知,比较经常使用, 咱们在编写Dao层和Service层时,能够彻底不做异常处理,并且建立一个专门的异常通知切面,由这个异常处理通知类专门负责处理各类异常。