17-spring学习-AOP初步实现
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初步实现的更多相关文章
- [原创]java WEB学习笔记107:Spring学习---AOP切面的优先级,重用切点表达式
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记105:Spring学习---AOP介绍,相关概念,使用AOP,利用 方法签名 编写 AspectJ 切入点表达式
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记104:Spring学习---AOP 前奏,通过一个问题引入动态代理
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- spring 学习 AOP和IOC
自11开始接触三大框架,至今已俞5载, 当时风光无限的ssh,现在还在被广泛使用,并有扩大之势的只有spring了 spring主要特性,是广为使用的AOP(面向切面)和IOC(控制反转) 1.其中, ...
- Spring学习-- AOP入门动态代理
AOP 的拦截功能是由 java 中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常 ...
- 黑马Spring学习 AOP XML和注解配置 5种通知 切点切面通知织入
业务类 package cn.itcast.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoin ...
- Spring学习(二)——Spring中的AOP的初步理解[转]
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...
- Spring学习(二)——Spring中的AOP的初步理解
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...
随机推荐
- 斐波那契数列(python实现)
描述 一个斐波那契序列,F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2) (n>=2),根据n的值,计算斐波那契数F(n),其中0≤n≤1000. 输入 输入 ...
- VK Cup 2016 - Round 1 (Div. 2 Edition) A. Bear and Reverse Radewoosh 水题
A. Bear and Reverse Radewoosh 题目连接: http://www.codeforces.com/contest/658/problem/A Description Lima ...
- 如何监控ActiveMQ
如何监控ActiveMQ在ActiveMQ 4.x中你可以监控代理并查看使用了哪些目标,和连接一起的活动和订阅使用下面的工具进行查看: JMX和JMX控制台,如jConsole http://java ...
- ExifInterface针对照片的使用
ExifInterface是保存照片信息的,那么我们在有需要的时候就可以通过这类,来获取照片的一些数码参数来做适当来逻辑处理,比较典型的案例就是android有的机型拍照或者选择照片后,照片可能会被旋 ...
- Spring EL hello world实例
Spring EL与OGNL和JSF EL相似,计算评估或在bean创建时执行.此外,所有的Spring表达式都可以通过XML或注解. 在本教程中,我们将学习如何使用Spring表达式语言(SpEL) ...
- JSON数据转换到POCO的代码
转载:http://www.cnblogs.com/wintersun/archive/2012/09/14/2684708.html 在Visual Studio 2012中轻松把JSON数据转换到 ...
- System.Threading.Tasks.Task 任务引起的IIS应用程序池崩溃
转载:http://www.cnblogs.com/aaa6818162/p/4421305.html 问题现象 IIS应用程序池崩溃(Crash)的特征如下: 1. 从客户端看,浏览器一直处于连接状 ...
- GridView 内容自动换行 简单记录
$("#GridView1 tr td:last-child").each(function () { var width = $(document).width() - 700. ...
- Spring事务为什么不会自动回滚?Spring事务怎样才会自动回滚?事务自动回滚条件及手动回滚
原文:https://blog.csdn.net/qq_32331073/article/details/76508147 更多Spring事务问题请访问链接:Spring事务回滚问题疑难详解 在此, ...
- 深拷贝(deep clone)与浅拷贝(shallow clone)
深拷贝(deep clone)与浅拷贝(shallow clone) 浅复制(浅克隆):被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复 ...