AOP是面向方面的编程,在实际开发中,AOP都会工作在业务层,因为业务层要调用数据层,而业务层也要完成所有辅助性的业务层操作。

范例:定义业务层操作接口:

package com.Spring.Service;
import com.Spring.Vo.Member; public interface IMemberService { public Boolean insert(Member vo);
}

实现操作接口:

package com.Spring.Service.Impl;
import org.springframework.stereotype.Service;
import com.Spring.Service.IMemberService;
import com.Spring.Vo.Member; @Service
public class IMemberServiceImpl implements IMemberService { @Override
public Boolean insert(Member vo) {
System.out.println("数据层调用 Member="+vo);
return false;
}
}

此时的业务层只关兴核心的业务功能,核心的功能就是调用了业务层代码。

随后所有的辅助性操作功能,都通过spring容器,动态配置。

范例:为项目配置Annotation的扫描支持:

base-package:表示扫描com.spring开头的包以下的文件,配合@Service注解,这个包以下的相关类会自动配置,代替一般的bean配置。

可以复习:http://www.cnblogs.com/alsf/p/7968072.html

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:annotation-config/>
<context:component-scan base-package="com.Spring"/>
</beans>

测试代码:

package com.Spring.Test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Spring.Service.IMemberService;
import com.Spring.Service.Impl.MemberServiceImpl;
import com.Spring.Vo.Member; public class TestMemberService { public static void main(String args[])
{
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
IMemberService ser=ctx.getBean("memberServiceImpl",MemberServiceImpl.class);
Member vo=new Member();
vo.setMid("hello");
vo.setName("你好");
System.out.println(ser.insert(vo));
}
}

输出结果:

但是这种操作并不严格,还需要准备相应的辅助性功能,那么这些辅助性的功能,可以单独定义在一个切面处理的类之中。

范例:定义切面处理类。

这里的切面类也用@Component做annotation配置,applicationcontext.xml文件里使用的时候直接使用serviceAspect就行了。

package com.Spring.aop;

import org.springframework.stereotype.Component;

@Component
public class ServiceAspect { public void serviceBefore()
{
System.out.println("AOP切面执行日志记录操作");
} public void serviceAfter()
{
System.out.println("AOP切面执行事务处理操作");
}
}

默认情况下spring不会开启切面。引入AOP命名空间。

范例:修改applicationContext.xml文件

勾选上:

代码中多了这些:

下面在XML文件中配置文件组织切面。

范例:定义切面引用

    <aop:config>
<!-- 定义程序的切入点,这里exucution表示对哪个包下面的类进行切入 -->
<aop:pointcut expression="execution(* com.Spring..*.*(..)))" id="pointcut"/>
<!-- 这里ref的对象是通过annotation配置@Component出来的, -->
<!-- 定义面向方面的处理类 -->
<aop:aspect ref="serviceAspect">
       <!--aop:before和aop:xx 里面需要pointcut-ref,表示依赖哪个切入点。-->
<aop:before method="serviceBefore" pointcut-ref="pointcut"/>
<aop:after method="serviceAfter" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>

重新执行最开始的Test类,发现报错:

Bean named 'memberServiceImpl' must be of type [com.Spring.Service.Impl.MemberServiceImpl], but was actually of type [com.sun.proxy.$Proxy8]

网上查询得知:

使用了jdk的自动动态代理,需要在<aop:aspectj-autoproxy中添加proxy-target-class="true"

    <aop:config>
<!-- 定义程序的切入点 -->
<aop:pointcut expression="execution(* com.Spring..*.*(..)))" id="pointcut"/>
<!-- 这里ref的对象是通过annotation配置@Component出来的, -->
<!-- 定义面向方面的处理类 -->
<aop:aspect ref="serviceAspect">
<aop:before method="serviceBefore" pointcut-ref="pointcut"/>
<aop:after method="serviceAfter" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy proxy-target-class="true"/>

执行后结果:

此时的业务层里面还没有出现任何的与业务层的核心操作有关的代码。而所有的辅助功能都会以切面的形式出现在项目的执行过程之中,而

这些切面就是最早的代理类

步骤:

1,首先需要定义一个切面aop:pointcut ,里面包含这个切面所覆盖的位置,由表达式expression决定,然后还需要一个id值。

2,然后定义一个面向方面的处理类;aop:aspect,里面需要指定这个类的实例是哪个,上面用ref和annotation配置组合确定了。

3,分别指定由aop:aspect指定的处理类的aop:before,aop,after等方法,里面需要指定这个方法关联哪个切面,通过pointcut-ref指定切面,然后就会对该切面所

覆盖指定的类的对象,进行切面处理了,比如每次相关类实例对象调用方法的时候,aop:befer等方法也会被调用。

分析结果:

这里切面和我们的Service类关联起来的地方就是定义切面处的 expression="execution(* com.Spring..*.*(..)))" 。

只要符合这个表达式的类,这里就是这个包下面的类,的对象实例执行,在执行前和执行后都会调用切面类里面的方法,具体调用哪个方法

,有aop:before,或者aop:xxx 绝对。

整个配置过程中,其基本的操作意义基本一看明白,但是最重要的是切入点的设置。

execution(* com.Spring..*.*(..)))

这种语法就是AspectJ定义的切入点操作语法。此语法结构如下:

excution(修饰符匹配? 返回值类型  操作类型的匹配?  名称匹配(参数匹配) 抛出异常匹配)

这里的?表示一个或0个。

以上语法详细解释如下:

1,修饰符:public  private ,只能出现0次或1次,(本次没有出现,默认public)

2,返回值:execution(* com.Spring..*.*(..)))。如果使用的是*,表示返回任意类型。

3,名称匹配:execution(* com.Spring..*.*(..))),表示的是具体要使用的此切面的程序类,如果写的是com.Spring表示这个包中的,

而如果出现“..”,则表示在任意子包下,随后的*.*表示任意类的任意方法,第一个*表示类名称,第二个表示方法名称

4,方法参数:execution(* com.Spring..*.*(..))),使用“..”表示使用任意多个参数,如果使用的是“*”,表示匹配任意一个参数。

 比如execution(* com.Spring..*.*(..)))就表示:在com.spring这个包下,任意返回值的任意类的,任意方法中,任意参数的地方,都要执行这个切面的拦截。

一旦拦截成功,就触发相应的处理方法,让我们的切面执行

17-spring学习-AOP初步实现的更多相关文章

  1. [原创]java WEB学习笔记107:Spring学习---AOP切面的优先级,重用切点表达式

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. [原创]java WEB学习笔记105:Spring学习---AOP介绍,相关概念,使用AOP,利用 方法签名 编写 AspectJ 切入点表达式

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. [原创]java WEB学习笔记104:Spring学习---AOP 前奏,通过一个问题引入动态代理

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. spring 学习 AOP和IOC

    自11开始接触三大框架,至今已俞5载, 当时风光无限的ssh,现在还在被广泛使用,并有扩大之势的只有spring了 spring主要特性,是广为使用的AOP(面向切面)和IOC(控制反转) 1.其中, ...

  6. Spring学习-- AOP入门动态代理

    AOP 的拦截功能是由 java 中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常 ...

  7. 黑马Spring学习 AOP XML和注解配置 5种通知 切点切面通知织入

    业务类 package cn.itcast.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoin ...

  8. Spring学习(二)——Spring中的AOP的初步理解[转]

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  9. Spring学习(二)——Spring中的AOP的初步理解

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

随机推荐

  1. ZOJ 3624 Count Path Pair 排列组合

    思路:在没有限制条件时,很容易知道结果为C(m+n,n)*C(m+q-p,q). 然后再把相交的情况去除就可以了.而如果想到了就是水题了…… 求A->D,B->C相交的情况可以转化为求A- ...

  2. bzoj 3595

    Splay 每个节点维护一个区间. /************************************************************** Problem: 3595 User ...

  3. Django Pagination

    Django provides a few classes that help you manage paginated data – that is, data that’s split acros ...

  4. nginx出现504 Gateway Time-out的解决思路

    http://www.xbc.me/nginx-fix-504-gateway-timeout/ 在安装完Nginx+PHP-fpm+Mysql后 (如何安装LNMP环境,请参考快速配置LNMP环境N ...

  5. 使用STL中的list容器实现单链表的操作

    #include<iostream> #include<list> #include<algorithm> using namespace std; void Pr ...

  6. Windows Embedded Compact 7网络编程概述(下)

    11.1.1 Select I/O模型 在Windows CE中,Select模型是唯一被支持的I/O模型.Select I/O模型就是利用select函数对I/O进行管理. 函数select的功能在 ...

  7. TortoiseSVN解决冲突

    解决冲突Resolving Conflicts有时候,你从仓库更新文件时会发生一些冲突.当两个或更多开发人员对同一个文件的某几行做 了修改,就会产生冲突.因为Subversion对你的项目一无所知,他 ...

  8. Linux使用jstat命令查看jvm的GC情况(转)

    B. jstack jstack主要用来查看某个Java进程内的线程堆栈信息.语法格式如下: 1 jstack [option] pid 2 jstack [option] executable co ...

  9. Fiddler2 抓取手机APP数据包

    原文:http://blog.goyiyo.com/archives/2044 下载安装运行后,查出运行机器的IP,手机连接同一网域内的WIFI,手机WIFI连接设置里的高级里,代理设置填写上Fidd ...

  10. Ext Connection

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...