AOP编程

1.为什么会有AOP?

        开发人员在编写应用程序的时候,通常包含两种代码:一种是和业务系统有关系的代码,一种是和业务系统关系不大的代码,列如日志,事务处理,权限处理等等。以前的程序中,这两种代码是写在一起的。这样一来程序中到处充满了相同或类似的代码,不利于维护。而AOP的目的就是让这两种代码分离解耦,这样程序员就能专心于业务处理,而且达到维护和重用的目的。

2.AOP的思想。

        就拿日志记录这个列子来看。每个方法都需要日志记录,不使用AOP的时候,每个方法中都要包含日志记录的代码,这样就会产生从复,而且日志记录和业务代码紧紧耦合,不利于维护。使用AOP的思想,可以把日志看成一个切面,所有需要日志记录的方法都要经过这个切面。这样就可以把日志记录代码封装,当方法经过切面的时候执行,这样就实现了代码重用了。

3.AOP术语

Aspect(切面):

将散落于各个业务逻辑之中的Cross-cutting concerns收集起来,设计成各个独立可重用的对象,这些对象称为Aspect

例:动态代理中的LogHandler就是一个Aspect

Advice(增强):

在特定的连接点上执行的动作,执行的这个动作就相当于对原始对象的功能做了增强。

Aspect对Cross-cutting concerns(横切关注点)的具体实现称为Advice。

Advice中包括了Cross-cutting concerns的行为或所要提供的服务

例:在动态代理的示例中代理类的invoke()就是Advice的具体实例

Joinpoint(连接点):

Advice在应用程序执行时加入业务流程的点或时机称为Joinpoint,具体来说就是Advice在应用程序中被执行的时机

Spring只支持方法的Joinpoint,执行时机可能是某个方法被执行之前或之后

Pointcut(切入点):切入点就是一系列连接点的集合。

Pointcut定义了感兴趣的Joinpoint,当调用的方法符合Pointcut表示式时,将Advice织入应用程序上提供服务

在Spring中,您可以在定义文件或Annotation中编写Pointcut,说明哪些Advice要应用至方法的前后

Target(目标对象):真正执行业务逻辑的对象

一个Advice被应用的对象或目标对象,也就是被代理的类

例:在动态代理的示例中HelloSpeaker就是LogHandler中Advice的Target 

Weave(织入):将切面整合到程序的执行流程中

Advice被应用至对象之上的过程称为织入,在AOP中织入的方式有几个时间点:

编译时期

类加载时期

执行时期

4.编写第一个AOP程序

案列分析:创建一个游戏类,玩家在玩游戏的时候,模拟玩家购买装备,装备升级玩家属性,提到啥刚还和防御等。

1)首先写代码 package com.gxa.bj.aspect

/**
 * @author chenqing
 *这是一个切面的类,这个切面类为游戏提供装备
 */
public class Equip {
    public void before(){//增强方法前的调用
    	System.out.println("选择了一件装备");
    }
    /**
     * @param joinpoint
     * @return
     * @throws Throwable
     * 正在增强的方法
     */
    public Object around(ProceedingJoinPoint joinpoint) throws Throwable{
    	Object object = joinpoint.proceed();
    	System.out.println("正在增强的方法");
    	System.out.println("杀伤力提高两倍,防御能力提高两倍");
    	return object;
    }      
    public void after(){ // 切面织入的方法使用完毕 
   	    System.out.println("装备使用完毕");
    }
}


2)编写业务处理代码。针对接口的编程package com.gxa.bj.service

先编写一个接口Play:

public interface Play {
    public void playGame();
}


编写用户:

public class RouseRole implements Play{
	@Override
	public void playGame() {
		// TODO Auto-generated method stub
		System.out.println("Rouse去打游戏");
	}
}
public class JeckRole implements Play{


	@Override
public void playGame() {
// TODO Auto-generated method stub
System.out.println("Jeck去打游戏");
}
}


3)编写切面和业务的bean对象,在配置前引入aop的命名空间:

xmlns:aop="http://www.springframework.org/schema/aop"<span style="white-space:pre">	</span>
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
                  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    <!-- 配置切面类 -->
    <bean id="equipbean" class="com.gxa.bj.aspect.Equip"/>
    <!-- 配置目标对象类 -->
    <bean id="Jeck" class="com.gxa.bj.service.JeckRole"/>
    <bean id="Rouse" class="com.gxa.bj.service.RouseRole"/>

4)配置AOP增强

 <aop:config>
       <aop:aspect id="equipaspect" ref="equipbean">
            <!-- 配置切入点,切入点要满足表达式 -->
            <aop:pointcut expression="execution(* com.gxa.bj.service.*.*(..))" id="pointcut"/>
            <!-- 要植入增强方法的匹配 -->
            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:around method="around" pointcut-ref="pointcut"/>
            <aop:after method="after" pointcut-ref="pointcut"/>
       </aop:aspect>
    </aop:config>

5)在程序中调用(注意,动态代理针对的是接口编程)

ApplicationContext appcontext = new ClassPathXmlApplicationContext("applicationContext.xml");
	    Play Jeckplay=(Play) appcontext.getBean("Jeck");
	    Play Rouseplay=(Play) appcontext.getBean("Rouse");
	    Jeckplay.playGame();
	    Rouseplay.playGame();

关于切面表达式的说明:

1.方法签名定义切入点举例:

1)execution(public * *(..)) 

匹配所有目标类的public方法,其中第一个*表示返回类型,第二个*表示方法名,其中..表示任意类型和个数的参数

2)execution(* find*(..)):匹配所有目标类以find为前缀的方法

2.通过类定义切入点

execution(*  com.gxa.bj.service.ZhangSanService.*(..))匹配该业务类下所有的方法。

3.通过类包定义切入点

execution(* com.gxa.bj.service.*(..):匹配该包下所有的的类和方法 

   execution(* com.gxa.bj.service..*(..):匹配该包下,子孙包下所有类的方法。注意:如果..出现在类名中,后面必须跟上*

4.通过方法形参定义切入点。

 execution(* meet(String,int)):匹配所有包的meet方法,且参数为String 类和int类型的 














































































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值