一、實驗目的:
(1)熟練掌握AOP術語(切面、切入點、通知等);
(2)熟練掌握基於XML和註解的AspectJ開發。
二、實驗內容:
使用前置通知進行訪問控制:通過方法參數決定是否可以訪問該方法,當參數值爲"agree"時允許訪問,否則不允許訪問。
三、實現方法與代碼
方法1.基於XML的聲明式AspectJ實現:
第一步:
1.建立dao接口(規範化模擬數據庫訪問)
package dao;
public interface TestDao {
public void visitdao(String str);
}
2.實現dao接口
package dao;
public class TestDaoImpl implements TestDao{
@Override
public void visitdao(String str) {
System.out.println("用戶權限:"+str+";成功訪問!!");
}
}
第二步:
1.定義切面
package aspectj.xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect {
/**
* 當參數值爲“agree”時纔可以訪問
*/
public void before(JoinPoint pjp) throws Throwable{
System.out.println("====基於XML的聲明式AspectJ的前置通知====");
//獲取當前請求方法的參數值
Object[] args = pjp.getArgs();
if(args[0].toString().equals("agree")) {
System.out.println("請求成功!");
//執行目標類的方法(此處必須要拋出異常)
// Object obj = pjp.proceed();
}else {
System.out.println("請求失敗,拒絕訪問!");
// 由於前置通知是切入在方法執行前,所以爲了防止他執行visitdao,此處拋出一個異常
// System.exit(-1);
if(true) {
throw new Exception("非法訪問");
}
}
}
}
第三步:
xml配置文件
<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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--定義目標對象,被切的 -->
<bean id="testDao" class="dao.TestDaoImpl"/>
<!--定義切面,切別人的 -->
<bean id="myAspect" class="aspectj.xml.MyAspect"/>
<!--AOP配置-->
<aop:config>
<!-- 配置切面 -->
<aop:aspect ref="myAspect">
<!--配置切入點,通知增強哪些方法 -->
<aop:pointcut expression="execution(* dao.*.*(..))" id="pointcut"/>
<aop:before method="before" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
第四步:
編寫測試類(main):
package aspectj.xml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.TestDao;
public class AspectjXmlTest {
@SuppressWarnings("resource")
public static void main(String[] args) {
try{
//從xml加載容器
ApplicationContext appCon = new ClassPathXmlApplicationContext("/aspectj/xml/applicationContext.xml");
//從容器中獲取到目標對象(被切類)
TestDao testDao = (TestDao)appCon.getBean("testDao");
//給目標對象方法參數傳參
testDao.visitdao("agree");
testDao.visitdao("Topus");
}catch(Exception e){
System.out.println("出現異常:"+e); //打印異常信息
// e.printStackTrace(); //打印完整的異常信息
}
}
}
方法2.基於註解的聲明式AspectJ
第一步:
同上,建立模擬的數據庫操作dao類
第二步:
定義切面:(註解方式)
package aspectj.annotation;
import org.aspectj.lang.JoinPoint;
//import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
//定義切入點
@Pointcut("execution(* dao.*.*(..))")
private void myPointCut() {
}
@Around("myPointCut()")
public Object before(JoinPoint pjp) throws Throwable {
System.out.println("====基於註解的聲明式AspectJ的前置通知====");
//獲取當前請求方法的參數值
Object[] args = pjp.getArgs();
if(args[0].toString().equals("agree")) {
System.out.println("請求成功!");
}else {
System.out.println("請求失敗,拒絕訪問!");
// 由於前置通知是切入在方法執行前,所以爲了防止他執行visitdao,此處拋出一個異常
// System.exit(-1);
if(true) {
throw new Exception("非法訪問");
}
}
return null;
}
}
第三步:
配置xml,此處只要指定掃描哪裏的註解即可
<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"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--指定需要掃描的包,使註解生效 -->
<context:component-scan base-package="aspectj.annotation"/>
<!-- 啓動基於註解的AspectJ支持 -->
<aop:aspectj-autoproxy/>
<!-- 控制反轉 -->
<bean id="testDao" class="dao.TestDaoImpl"/>
</beans>
第四步:
創建測試類:
package aspectj.annotation;
//import java.util.Scanner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.TestDao;
public class AspectjAnnotationTest {
public static void main(String[] args) {
try{
//從xml加載容器
@SuppressWarnings("resource")
ApplicationContext appCon = new ClassPathXmlApplicationContext("/aspectj/annotation/applicationContext.xml");
//從容器中獲取到目標對象(被切類)
TestDao testDao = (TestDao)appCon.getBean("testDao");
//給目標對象方法參數傳參
testDao.visitdao("agree");
testDao.visitdao("Topus");
}catch(Exception e){
System.out.println("出現異常:"+e); //打印異常信息
// e.printStackTrace(); //打印完整的異常信息
}
}
}