您的位置:首页 > 编程语言

AOP面向切面编程的四种实现

2016-10-13 10:36 721 查看
一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP、代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及BeanNameAutoProxyCreator代理、Aspectj的注解和xml配置文件。

1.代理工厂bean(ProxyFacteryBean)的方式

1.1 接口(Interface)

1 package cn.happy.interfaces;
2
3 public interface Advice {
4
5     public void fristMethod();
6
7     public String secondMethod();
8 }


1.2 接口的实现类

1 package cn.happy.impl;
2
3 import cn.happy.interfaces.Advice;
4
5 public class AdviceImpl implements Advice {
6
7     public void fristMethod() {
8          System.out.println("==fristMethod==");
9     }
10
11     public String secondMethod() {
12         System.out.println("==secondMethod==");
13         return "abc";
14     }
15
16 }


1.3 各种通知增强

1.3.1 前置增强

1 package cn.happy.advice;
2
3 import java.lang.reflect.Method;
4
5 public class MethodBeforeAdvice implements
6         org.springframework.aop.MethodBeforeAdvice {
7
8     public void before(Method arg0, Object[] arg1, Object arg2)
9             throws Throwable {
10         System.out.println("==Before==");
11
12     }
13
14 }


1.3.2 后置增强

1 package cn.happy.advice;
2
3 import java.lang.reflect.Method;
4
5 import org.springframework.aop.AfterReturningAdvice;
6
7 public class AfterReturningAdvie implements AfterReturningAdvice {
8
9     public void afterReturning(Object arg0, Method arg1, Object[] arg2,
10             Object arg3) throws Throwable {
11         System.out.println("==After==");
12
13     }
14
15 }


1.3.3 环绕增强

package cn.happy.aroundadvice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyInterceptor implements MethodInterceptor{

public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("==before==");
String result= (String)invocation.proceed();
System.out.println("==after==");
return result;
}
}


1.3.4 异常增强

package cn.happy.exception;

import org.springframework.aop.ThrowsAdvice;

public class MyException implements ThrowsAdvice {
public void afterThrowing(Exception ex){
System.out.println("异常通知");
}
}


1.4 配置文件

<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 实现类的引入 -->
<bean id="adviceimpl" class="cn.happy.impl.AdviceImpl"></bean>
<!-- 前置增强  通知-->
<bean id="advicebefore" class="cn.happy.advice.MethodBeforeAdvice"></bean>
<!-- 后置增强  通知-->
<bean id="adviceafter" class="cn.happy.advice.AfterReturningAdvie"></bean>

<!-- 环绕增强 -->
<bean id="around" class="cn.happy.aroundadvice.MyInterceptor"></bean>

<!-- 关联  代理工厂bean ProxyFacteryBean 通知 -->
<!--<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="targetName" value="adviceimpl"></property>
<property name="interceptorNames" value="advicebefore,adviceafter"></property>

</bean>-->

<!-- 环绕增强 代理工厂 顾问包装通知 -->
<bean id="aroundserviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="target" ref="adviceimpl"></property>
<property name="interceptorNames" value="beforeadvisor"></property>

</bean>

<!-- 切面  通知  -->
<bean id="beforeadvice" class="cn.happy.mymethodbefore.MyMethodBeforeAdvice"></bean>

<!-- 顾问  包装advice -->
<bean id="beforeadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="beforeadvice"></property>
<property name="mappedNames" value="fristMethod,secondMethod"></property>
</bean>

<!-- 顾问  包装advice 正则表达式-->
<!--<bean id="beforeadvisor1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="beforeadvice"></property>
<property name="pattern" value=".*Method.*"></property>
</bean>-->

<!-- 默认自动代理  默认只找通知-->
<!--<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>-->

<!-- beanname自动代理 可以选择顾问或者通知-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="adviceimpl"></property>
<property name="interceptorNames" value="beforeadvisor"></property>
</bean>

</beans>


1.5 测试类

package cn.happy.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.interfaces.Advice;

public class Test {
/**
* 通知的前置和后置测试
*/
public static void main(String[] args) {
//解析配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
Advice advice= (Advice)ctx.getBean("adviceimpl"); //自动代理beanname的方式
advice.fristMethod();
advice.secondMethod();
}
}


2. 最原始的经典AOP

2.1 最基本分层模式dao、biz、service以及最后测试Test

2.1.1DAO层

package cn.happy.dao;

import cn.happy.entity.User;

//接口
public interface UDao {

//保存方法
public void save(User user);
}

//实现类
package cn.happy.dao;

import cn.happy.entity.User;

public class UserDaoImpl implements UDao{

public void save(User user) {
System.out.println("保存成功");
}

}


2.1.2 BIZ层

package cn.happy.biz;

import cn.happy.entity.User;

//业务接口
public interface UBiz {

//保存方法
public void save2(User user);
}

//业务实现类
package cn.happy.biz;

import cn.happy.dao.UDao;
import cn.happy.entity.User;

public class UserBiz implements UBiz{

//dao的对象
private UDao udao;
public void save2(User user) {
udao.save(user);

}
public UDao getUdao() {
return udao;
}
public void setUdao(UDao udao) {
this.udao = udao;
}

}


2.1.3 AOP模块即service层

package cn.happy.logger;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

//前置内容
public class LoggerBefore implements MethodBeforeAdvice {

public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
System.out.println("save前置内容");
}
}

//后置内容
package cn.happy.logger;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;

public class LoggerAfter implements AfterReturningAdvice{

public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
System.out.println("save后置内容");
}
}


2.1.4 经典的配置文件

<?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: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-4.1.xsd">
<!-- 业务biz与dao接口对象的实现 -->
<bean id="dao" class="cn.happy.dao.UserDaoImpl"></bean>
<bean id="biz" class="cn.happy.biz.UserBiz">
<property name="udao" ref="dao"></property>
</bean>
<!-- 前置与后置内容的配置 -->
<bean id="before" class="cn.happy.logger.LoggerBefore"></bean>
<bean id="after" class="cn.happy.logger.LoggerAfter"></bean>
<!-- aop的配置 -->
<aop:config>
<aop:pointcut expression="execution(public void save2(cn.happy.entity.User))" id="pointcut"/>
<!-- 在切入点处插入增强处理、完成"织入" -->
<aop:advisor advice-ref="before" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="after" pointcut-ref="pointcut"/>
</aop:config>
</beans>


2.1.5 测试类

package cn.happy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.biz.UBiz;
import cn.happy.entity.User;

public class AOPTest {

public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UBiz ubiz=(UBiz)context.getBean("biz");
User user=new User();
ubiz.save2(user);
System.out.println("save~ok");
}
}


3. 然后就是Aspectj的注解以及xml配置文件的两种方式了。

3.1 Aspectj注解

3.1.1 接口和实现类

package cn.happy.impl;
//接口
public interface AspectDao {

public void add();
public void delete();
}

//实现类
package cn.happy.impl;

public class AspectjIpml implements AspectDao{
//添加
public void add() {
System.out.println("==ADD==");
}
//删除
public void delete() {
System.out.println("==DELETE==");
}
}


3.1.2 注解类Aspect

package cn.happy.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Before;

@org.aspectj.lang.annotation.Aspect
public class Aspect {
//前置增强
@Before(value="execution(public * *(..))")
public void asBefore(){
System.out.println("这是前置增强");
}
//后置增强
@AfterReturning(value="execution(public * *(..))")
public void asAfterReturning(){
System.out.println("这是后置增强");
}
//环绕增强
@Around(value="execution(public * *(..))")
public void asAround(ProceedingJoinPoint pj){
System.out.println("这是环绕前置增强");
try {
pj.proceed();
} catch (Throwable e) {
//抓捕异常
e.printStackTrace();
}
System.out.println("这是环绕后置增强");
}
//异常增强
@AfterThrowing(value="execution(public * *(..))")
public void asThorws(){
System.out.println("这是异常增强");
}
//最终增强
@After(value="execution(public * *(..))")
public void asAfter(){
System.out.println("这是最终增强");
}
}


3.1.3 注解的配置文件

<?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: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.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.xsd">
<!-- 目标对象 -->
<bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>
<!-- 增强类 -->
<bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>
<!-- 扫描整个项目 关联注解类和实现类 -->
<aop:aspectj-autoproxy />

</beans>


3.1.4 测试类

package cn.happy.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.happy.impl.AspectDao;

public class AspectjTest {
/**
* 注解测试 */
public static void main(String[] args) {
// 解析配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
AspectDao aspect = (AspectDao) ctx.getBean("aspectimpl");
aspect.add();
aspect.delete();
}
}


4. Aspectj的XML配置法,其他的基本都一样只要修改Aspectj增强类和配置文件就行了

4.1 Aspect增强类只需将那些注解消去即可

package cn.happy.aspectj;
import org.aspectj.lang.ProceedingJoinPoint;

public class Aspect {
//前置增强
public void asBefore(){
System.out.println("这是前置增强");
}
//后置增强
public void asAfterReturning(){

System.out.println("这是后置增强");
}
//环绕增强
public void asAround(ProceedingJoinPoint pj){
System.out.println("这是环绕前置增强");
try {
pj.proceed();
} catch (Throwable e) {
//抓捕异常
e.printStackTrace();
}
System.out.println("这是环绕后置增强");
}
//异常增强
public void asThorws(){

System.out.println("这是异常增强");
}
//最终增强
public void asAfter(){

System.out.println("这是最终增强");
}
}


4.2 XML的配置文件会稍微会复杂一点,但大致的还是跟对原始的经典aop实现方式相同

<?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: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.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.xsd">
<!-- 目标对象 -->
<bean id="aspectimpl" class="cn.happy.impl.AspectjIpml"></bean>
<!-- 增强类 -->
<bean id="aspectj" class="cn.happy.aspectj.Aspect"></bean>
<!-- Aspectj的XML配置文件 -->
<aop:config>
<aop:pointcut expression="execution(public * *(..))" id="pointcut"/>
<aop:aspect ref="aspectj">
<aop:before method="asBefore" pointcut-ref="pointcut"/>
<aop:after-returning method="asAfterReturning" pointcut-ref="pointcut"/>
<aop:after-returning method="asAround(org.aspectj.lang.ProceedingJoinPoint)" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>


好了,这就是AOP(面向切面编程)的四种实现方式了。希望你们看了之后能让你们对AOP面向切面编程思想有更深的了解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: