先来一个HelloWorld的简单例子,开开胃,爽一下~!
1、Aop配置文件spring-aop.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:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xsi:schemaLocation=
- "http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
- ">
- <bean id = "helloWorldServiceImpl" class="com.spring.xkey.aop.HelloWorldServiceImpl">
- </bean>
- <bean id = "aspect" class = "com.spring.xkey.aop.HelloWorldAspect">
- </bean>
- <aop:config>
- <aop:pointcut id="pointcut" expression="execution(* com.spring..*.sayHello(..)) and args(user)"/>
- <aop:aspect ref="aspect">
- <aop:before pointcut-ref = "pointcut" method="beforeAdvice(java.lang.String)" arg-names="user"/>
- <aop:after pointcut="execution(* com.spring..*.sayHello(..))" method="afterAdvice"/>
- <aop:after-returning pointcut="execution(* com.spring..*.sayAfterReturning(..))"
- method="afterReturningAdvice"
- arg-names="value"
- returning="value"/>
- <aop:after-throwing pointcut="execution(* com.spring..*.sayAfterThrowing(..))"
- method="afterThrowingAdvice"
- arg-names="e"
- throwing="e"/>
- <aop:around pointcut="execution(* com.spring..*.sayAround(..))"
- method="aroundAdvice"
- />
- </aop:aspect>
- </aop:config>
- </beans>
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id = "helloWorldServiceImpl" class="com.spring.xkey.aop.HelloWorldServiceImpl">
</bean>
<bean id = "aspect" class = "com.spring.xkey.aop.HelloWorldAspect">
</bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.spring..*.sayHello(..)) and args(user)"/>
<aop:aspect ref="aspect">
<aop:before pointcut-ref = "pointcut" method="beforeAdvice(java.lang.String)" arg-names="user"/>
<aop:after pointcut="execution(* com.spring..*.sayHello(..))" method="afterAdvice"/>
<aop:after-returning pointcut="execution(* com.spring..*.sayAfterReturning(..))"
method="afterReturningAdvice"
arg-names="value"
returning="value"/>
<aop:after-throwing pointcut="execution(* com.spring..*.sayAfterThrowing(..))"
method="afterThrowingAdvice"
arg-names="e"
throwing="e"/>
<aop:around pointcut="execution(* com.spring..*.sayAround(..))"
method="aroundAdvice"
/>
</aop:aspect>
</aop:config>
</beans>
2、HelloWorldService接口
- package com.spring.xkey.aop;
- public interface HelloWorldService {
- public void sayHello(String username);
- public boolean sayAfterReturning();
- public void sayAfterThrowing();
- public int sayAround(String username,String password);
- }
package com.spring.xkey.aop;
public interface HelloWorldService {
public void sayHello(String username);
public boolean sayAfterReturning();
public void sayAfterThrowing();
public int sayAround(String username,String password);
}
3、HelloWorldServiceImpl类
- package com.spring.xkey.aop;
- import java.lang.RuntimeException;
- public class HelloWorldServiceImpl implements HelloWorldService{
- public void sayHello(String username){
- System.out.println("My first Aop test "+username);
- }
- public boolean sayAfterReturning(){
- System.out.println("after returning");
- return true;
- }
- public void sayAfterThrowing(){
- System.out.println("After throwing");
- throw new RuntimeException();
- }
- public int sayAround(String username,String password){
- System.out.println("Around::: "+username+", "+password);
- int val = 1;
- return val;
- }
- }
package com.spring.xkey.aop;
import java.lang.RuntimeException;
public class HelloWorldServiceImpl implements HelloWorldService{
public void sayHello(String username){
System.out.println("My first Aop test "+username);
}
public boolean sayAfterReturning(){
System.out.println("after returning");
return true;
}
public void sayAfterThrowing(){
System.out.println("After throwing");
throw new RuntimeException();
}
public int sayAround(String username,String password){
System.out.println("Around::: "+username+", "+password);
int val = 1;
return val;
}
}
4、具体实现AOP编程的HelloWorldAspect类
- package com.spring.xkey.aop;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- public class HelloWorldAspect {
- public void beforeAdvice(String user){
- //System.out.println(jp.getArgs()[0].toString());
- System.out.println("before advice " + user);
- }
- public void afterAdvice(JoinPoint jp){
- System.out.println("after advice "+jp.getArgs()[0].toString());
- }
- public void afterReturningAdvice(Object value){
- System.out.println("afterReturning advice "+value);
- }
- public void afterThrowingAdvice(Exception e){
- System.out.println("after throwing advice exception:" + e);
- }
- public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable{
- /**System.out.println(pjp.toLongString());
- System.out.println(pjp.getSignature().toString());
- System.out.println(pjp.getKind().toString());
- System.out.println(pjp.getArgs()[0].toString());
- System.out.println("name+psd");*/
- Object [] obj = pjp.getArgs();
- String username = (String) obj[0];
- String password = (String) obj[1];
- System.out.println(username+","+password);
- Object retVal;
- if(username.equals("xkey") && password.equals("color")){
- retVal = pjp.proceed();
- }else{
- retVal = pjp.proceed(new Object[]{"ideal","*******"});
- }
- System.out.println("name+psd");
- if(retVal == null) System.out.println("false");
- else{
- System.out.println(retVal.toString());
- }
- return 2;
- }
- }
package com.spring.xkey.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class HelloWorldAspect {
public void beforeAdvice(String user){
//System.out.println(jp.getArgs()[0].toString());
System.out.println("before advice " + user);
}
public void afterAdvice(JoinPoint jp){
System.out.println("after advice "+jp.getArgs()[0].toString());
}
public void afterReturningAdvice(Object value){
System.out.println("afterReturning advice "+value);
}
public void afterThrowingAdvice(Exception e){
System.out.println("after throwing advice exception:" + e);
}
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable{
/**System.out.println(pjp.toLongString());
System.out.println(pjp.getSignature().toString());
System.out.println(pjp.getKind().toString());
System.out.println(pjp.getArgs()[0].toString());
System.out.println("name+psd");*/
Object [] obj = pjp.getArgs();
String username = (String) obj[0];
String password = (String) obj[1];
System.out.println(username+","+password);
Object retVal;
if(username.equals("xkey") && password.equals("color")){
retVal = pjp.proceed();
}else{
retVal = pjp.proceed(new Object[]{"ideal","*******"});
}
System.out.println("name+psd");
if(retVal == null) System.out.println("false");
else{
System.out.println(retVal.toString());
}
return 2;
}
}
5、测试类
- package com.spring.xkey.aop;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class AopTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- ApplicationContext context =
- new ClassPathXmlApplicationContext("com/spring/xkey/aop/spring-aop.xml");
- HelloWorldService hello = (HelloWorldService)context.getBean("helloWorldServiceImpl");
- hello.sayHello("xkey");
- System.out.println("===================================");
- // hello.sayAfterReturning();
- // System.out.println("===================================");
- // hello.sayAfterThrowing();
- // System.out.println("===================================");
- Object val = (Object)hello.sayAround("xkey", "colo");
- System.out.println(val.toString());
- }
- }
package com.spring.xkey.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context =
new ClassPathXmlApplicationContext("com/spring/xkey/aop/spring-aop.xml");
HelloWorldService hello = (HelloWorldService)context.getBean("helloWorldServiceImpl");
hello.sayHello("xkey");
System.out.println("===================================");
// hello.sayAfterReturning();
// System.out.println("===================================");
// hello.sayAfterThrowing();
// System.out.println("===================================");
Object val = (Object)hello.sayAround("xkey", "colo");
System.out.println(val.toString());
}
}
6、AOP Around(环绕通知)可以控制返回对象,即你可以返回一个与目标对象完全不同的返回值,虽然这很危险,但是你却可以办到。目标方法的返回值 就是 环绕通知的返回值。proceed() 方法可以在通知体内调用一次、多次 或根本不用调用;还可以控制执行方法的参数值。具体见aroundAdvice方法的实现。
7、给个更直观的结果
- before advice xkey
- My first Aop test xkey
- after advice xkey
- ===================================
- xkey,colo
- Around::: ideal, ********
- name+psd
- In the AroundAdvice the return value is 1
- After AroundAdvice modify return value is 2
before advice xkey
My first Aop test xkey
after advice xkey
===================================
xkey,colo
Around::: ideal, ********
name+psd
In the AroundAdvice the return value is 1
After AroundAdvice modify return value is 2
这里使用AOP Around就可以用来进行一个身份验证,通过面向切面编程(AOP)将验证部分独立出来,使得代码的耦合度降低,如果使用面向对象思想(OOP)就应该是独立写一个身份验证的方法,然后当需要使用该方法再去new 一个身份验证方法的类,然后传递参数通过验证类中的方法去验证,这样代码的耦合度就变强了。
通过Scheme配置实现AOP步骤
步骤一、编写业务类:
public class AspectBusiness {
//切入点
public String delete(String obj) {
System.out.println("==========调用切入点:" + obj + "说:你敢删除我!===========\n");
return obj + ":瞄~";
}
public String add(String obj) {
System.out.println("================这个方法不能被切。。。============== \n");
return obj + ":瞄~ 嘿嘿!";
}
public String modify(String obj) {
System.out.println("=================这个也设置加入切吧====================\n");
return obj + ":瞄改瞄啊!";
}
}
步骤二、编写切面类:切面类中,包含了所有的通知
public class AspectAdvice {
//前置通知
public void doBefore(JoinPoint jp) {
System.out.println("===========进入before advice============ \n");
System.out.print("准备在" + jp.getTarget().getClass() + "对象上用");
System.out.print(jp.getSignature().getName() + "方法进行对 '");
System.out.print(jp.getArgs()[0] + "'进行删除!\n\n");
System.out.println("要进入切入点方法了 \n");
}
// 后置通知
// @param jp
// 连接点
// @param result
// 返回值
public void doAfter(JoinPoint jp, String result) {
System.out.println("==========进入after advice=========== \n");
System.out.println("切入点方法执行完了 \n");
System.out.print(jp.getArgs()[0] + "在");
System.out.print(jp.getTarget().getClass() + "对象上被");
System.out.print(jp.getSignature().getName() + "方法删除了");
System.out.print("只留下:" + result + "\n\n");
}
// 环绕通知
// @param pjp
// 连接点
public object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("===========进入around环绕方法!=========== \n");
// 调用目标方法之前执行的动作
System.out.println("调用方法之前: 执行!\n");
// 调用方法的参数
Object[] args = pjp.getArgs();
// 调用的方法名
String method = pjp.getSignature().getName();
// 获取目标对象
Object target = pjp.getTarget();
// 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
Object result = pjp.proceed();
System.out.println("输出:" + args[0] + ";" + method + ";" + target + ";" + result + "\n");
System.out.println("调用方法结束:之后执行!\n");
return result;
}
//异常通知
public void doThrow(JoinPoint jp, Throwable e) {
System.out.println("删除出错啦");
}
}
步骤四、配置文件的编写:
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default->
<!-- ==============================利用spring 利用aspectj来配置AOP================================ -->
<!-- 声明一个业务类 -->
<bean id="aspectBusiness" class="aop.schema.AspectBusiness" />
<!-- 声明通知类 -->
<bean id="aspectAdvice" class="aop.schema.advice.AspectAdvice" />
<aop:config>
<aop:aspect id="businessAspect" ref="aspectAdvice">
<!-- 配置指定切入的对象 -->
<aop:pointcut id="point_cut" expression="execution(* aop.schema.*.*(..))" />
<!-- 只匹配add方法作为切入点
<aop:pointcut id="except_add" expression="execution(* aop.schema.*.add(..))" />
-->
<!-- 前置通知 -->
<aop:before method="doBefore" pointcut-ref="point_cut" />
<!-- 后置通知 returning指定返回参数 -->
<aop:after-returning method="doAfter"
pointcut-ref="point_cut" returning="result" />
<aop:around method="doAround" pointcut-ref="point_cut"/>
<aop:after-throwing method="doThrow" pointcut-ref="point_cut" throwing="e"/>
</aop:aspect>
</aop:config>
</beans>
步骤五、测试类:
public class Debug {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aop/schema_aop.xml");
AspectBusiness business = (AspectBusiness) context.getBean("aspectBusiness");
business.delete("猫");
}
}