Guice 学习(八)AOP (面向切面的编程)
Guice的AOP还是非常弱的。眼下只支持方法级别上的,另外灵活性也不是非常高。
看例如以下演示样例:
Guice支持AOP的条件是:
类必须是public或者package (default)
类不能是final类型的
方法必须是public,package或者protected
方法不能使final类型的
实例必须通过Guice的@Inject注入或者有一个无參数的构造函数
且看演示样例代码
1、定义接口
package com.guice.AOP;
import com.google.inject.ImplementedBy;
@ImplementedBy(ServiceImpl.class)
public interface Service {
public void sayHello();
}
2、定义实现类
package com.guice.AOP;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
@Singleton
public class ServiceImpl implements Service {
@Named("log")
@Override
public void sayHello() {
System.out.println(String.format("[%s#%d] execute %s at %d", this.getClass().getSimpleName(), hashCode(), "sayHello", System.nanoTime()));
}
}
3、定义切面
package com.guice.AOP;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* TODO :自己定义的方法拦截器。用于输出方法的运行时间
*
* @author E468380
*/
public class LoggerMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String name = invocation.getMethod().getName();
long startTime = System.nanoTime();
System.out.println(String.format("before method[%s] at %s", name, startTime));
Object obj = null;
try {
obj = invocation.proceed();// 运行服务
} finally {
long endTime = System.nanoTime();
System.out.println(String.format("after method[%s] at %s, cost(ns):%d", name, endTime, (endTime - startTime)));
}
return obj;
}
}
4、測试类
package com.guice.AOP;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.matcher.Matchers;
import com.google.inject.name.Names;
public class AopTest {
@Inject
private Service service;
public static void main(String[] args) {
Injector injector = Guice.createInjector(new Module() {
@Override
public void configure(Binder binder) {
binder.bindInterceptor(Matchers.any(), Matchers.annotatedWith(Names.named("log")), new LoggerMethodInterceptor());
}
});
injector.getInstance(AopTest.class).service.sayHello();
injector.getInstance(AopTest.class).service.sayHello();
injector.getInstance(AopTest.class).service.sayHello();
}
}
输出结果:
before method[sayHello] at 18832801981960
[ServiceImpl$$EnhancerByGuice$$d4244950#1109685565] execute sayHello at 18832817170768
after method[sayHello] at 18832817378285, cost(ns):15396325
before method[sayHello] at 18832817542181
[ServiceImpl$$EnhancerByGuice$$d4244950#1109685565] execute sayHello at 18832817640327
after method[sayHello] at 18832817781772, cost(ns):239591
before method[sayHello] at 18832817920651
[ServiceImpl$$EnhancerByGuice$$d4244950#1109685565] execute sayHello at 18832818013023
after method[sayHello] at 18832818132657, cost(ns):212006
关于此结果有几点说明:
(1)因为使用了AOP我们的服务得到的不再是我们写的服务实现类了,而是一个继承的子类,这个子类应该是在内存中完毕的。
(2)除了第一次调用比較耗时外(可能guice内部做了比較多的处理)。其他调用事件为0毫秒(我们的服务本身也没做什么事)。
(3)确实完毕了我们期待的AOP功能。
5、切面注入依赖
假设一个切面(拦截器)也须要注入一些依赖怎么办?
在这里我们声明一个前置服务。输出全部调用的方法名称。
①定义接口
package com.guice.AOP;
import org.aopalliance.intercept.MethodInvocation;
import com.google.inject.ImplementedBy;
@ImplementedBy(BeforeServiceImpl.class)
public interface BeforeService {
void before(MethodInvocation invocation);
}
②定义实现类
package com.guice.AOP;
import org.aopalliance.intercept.MethodInvocation;
public class BeforeServiceImpl implements BeforeService {
@Override
public void before(MethodInvocation invocation) {
System.out.println("Before--->" + invocation.getClass().getName());
}
}
③定义切面
package com.guice.AOP;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import com.google.inject.Inject;
//这个切面依赖前置服务
public class AfterMethodIntercepter implements MethodInterceptor {
@Inject
private BeforeService beforeService;
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
beforeService.before(invocation);
Object obj = null;
try {
obj = invocation.proceed();
} finally {
System.out.println("after--->" + invocation.getClass().getName());
}
return obj;
}
}
④编写測试类
package com.guice.AOP;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.matcher.Matchers;
import com.google.inject.name.Names;
public class AopTest2 {
@Inject
private Service service;
public static void main(String[] args) {
Injector injector = Guice.createInjector(new Module() {
@Override
public void configure(Binder binder) {
AfterMethodIntercepter after = new AfterMethodIntercepter();
binder.requestInjection(after);
binder.bindInterceptor(Matchers.any(), Matchers.annotatedWith(Names.named("log")), after);
}
});
injector.getInstance(AopTest2.class).service.sayHello();
}
}
输出结果:
Before--->com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation
[ServiceImpl$$EnhancerByGuice$$618294e9#506575947] execute sayHello at 20140444543338
after--->com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation
说明
Binder绑定一个切面的API是:
com.google.inject.Binder.bindInterceptor(Matcher<? super Class<?
>>, Matcher<? super Method>, MethodInterceptor...)
第一个參数是匹配类,第二个參数是匹配方法,第三个数组參数是方法拦截器。也就是说眼下为止Guice只能拦截到方法,然后才做一些切面工作。
注意
虽然切面同意注入其依赖,可是这里须要注意的是。假设切面依赖仍然走切面的话那么程序就陷入了死循环,非常久就会堆溢出。
Guice的AOP还是非常弱的,眼下只支持方法级别上的。另外灵活性也不是非常高。
Guice 学习(八)AOP (面向切面的编程)的更多相关文章
- 学习笔记: AOP面向切面编程和C#多种实现
AOP:面向切面编程 编程思想 OOP:一切皆对象,对象交互组成功能,功能叠加组成模块,模块叠加组成系统 类--砖头 系统--房子 类--细胞 系统--人 ...
- AOP 面向切面的编程
一.面向切面的编程需求的产生 代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀.每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点. 代码分散: 以日志需求为例,只是为了 ...
- spring框架学习(三)——AOP( 面向切面编程)
AOP 即 Aspect Oriented Program 面向切面编程 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...
- java aop面向切面编程
最近一直在学java的spring boot,一直没有弄明白aop面向切面编程是什么意思.看到一篇文章写得很清楚,终于弄明白了,原来跟python的装饰器一样的效果.http://www.cnblog ...
- 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~
简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...
- Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存
本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...
- aop面向切面编程的实现
aop主要用于日志记录,跟踪,优化和监控 下面是来自慕课网学习的一些案例,复制黏贴就完事了,注意类和方法的位置 pom添加依赖: <dependency> <groupId>o ...
- AOP 面向切面编程, Attribute在项目中的应用
一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...
随机推荐
- SQL Server 删除表的默认值约束
首先查出字段的默认值约束名称,然后根据默认值约束名称删除默认值约束 ) select @constraintName = b.name from syscolumns a,sysobjects b w ...
- node.js从入门到放弃(二)
上章讲了学习node,应该去学习什么,对这些框架去进行学习现在咋们聊聊如何用原生来进行操作 主要来讲一下events-事件触发器 events是什么东西呢?他的英文翻译,活动,事件的意思,在计算机语言 ...
- Luogu P3806 点分治模板1
题意: 给定一棵有n个点的树询问树上距离为k的点对是否存在. 分析: 这个题的询问和点数都不多(但是显然暴力是不太好过的,即使有人暴力过了) 这题应该怎么用点分治呢.显然,一个模板题,我们直接用套路, ...
- set指令详解
set指令详解 功能说明:设置shell 语 法:set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...] 说 明:设置或取消设置shell选项 ...
- 树梅派 -- 通过/sys读写ADC芯片 pcf8591
通过wiringPi等library, 在user space 通过/dev/i2c来读写i2c设备的方案不在本文讨论了. 编译SENSORS_PCF8591 模块 在Default raspberr ...
- sorted倒序
''' sorted 可以排列list, reverse=True 可以倒序排列 ''' # # def list_Dict(x): # m = {} # for k,v in enumerate(x ...
- os操作文件
os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依 ...
- list、tuple、dict内部功能释义
一.list内部功能释义 运用频次:☆☆☆☆☆ 1. append():列表末尾插入元素 [示例] >>> L1=[11,22,33] >>> L1.append( ...
- H5在ios弹窗状态下调起输入法后关闭输入法页面元素错位解决办法
最近开发移动端,有个需求:点击退款弹出文本框和发送短信按钮,输入手机号码和验证码确定退款. 发现安卓手机没毛病,但是在ios手机上点击文本框调起输入法,此时点击完成或者关闭输入法就无法正常操作了,肉眼 ...
- [codeforces722D]Generating Sets
[codeforces722D]Generating Sets 试题描述 You are given a set Y of n distinct positive integers y1, y2, . ...