博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
17-spring学习-AOP初步实现
阅读量:5961 次
发布时间:2019-06-19

本文共 3739 字,大约阅读时间需要 12 分钟。

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;@Servicepublic 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

测试代码:

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;@Componentpublic class ServiceAspect {        public void serviceBefore()    {        System.out.println("AOP切面执行日志记录操作");    }        public void serviceAfter()    {        System.out.println("AOP切面执行事务处理操作");    }}

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

范例:修改applicationContext.xml文件

勾选上:

代码中多了这些:

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

范例:定义切面引用

       

重新执行最开始的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"  

执行后结果:

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

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

 

步骤:

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这个包下,任意返回值的任意类的,任意方法中,任意参数的地方,都要执行这个切面的拦截。

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

 

你可能感兴趣的文章
Vuex学习
查看>>
bootstrap - navbar
查看>>
切图崽的自我修养-[ES6] 编程风格规范
查看>>
服务器迁移小记
查看>>
FastDFS存储服务器部署
查看>>
Android — 创建和修改 Fragment 的方法及相关注意事项
查看>>
swift基础之_swift调用OC/OC调用swift
查看>>
Devexpress 15.1.8 Breaking Changes
查看>>
Java B2B2C多用户商城 springcloud架构- common-service 项目构建过程(七)
查看>>
ElasticSearch Client详解
查看>>
新零售讲堂之时代下的传统零售业,何去何从?
查看>>
c++读取和写入TXT文件的整理
查看>>
linux安全问答(1)
查看>>
mybatis update返回值的意义
查看>>
expdp 详解及实例
查看>>
解读最具O2O属性—哈根达斯微信企业号的成功之道
查看>>
Extjs4.x (MVC)Controller中refs以及Ext.ComponentQuery解析
查看>>
Server-01 How to Find the Remote Desktop Port
查看>>
Java--接口、抽象与继承
查看>>
通过IP判断登录地址
查看>>