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層時,能夠徹底不做異常處理,並且建立一個專門的異常通知切面,由這個異常處理通知類專門負責處理各類異常。