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 (面向切面的编程)的更多相关文章

  1. 学习笔记: AOP面向切面编程和C#多种实现

    AOP:面向切面编程   编程思想 OOP:一切皆对象,对象交互组成功能,功能叠加组成模块,模块叠加组成系统      类--砖头     系统--房子      类--细胞     系统--人    ...

  2. AOP 面向切面的编程

    一.面向切面的编程需求的产生 代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀.每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点. 代码分散: 以日志需求为例,只是为了 ...

  3. spring框架学习(三)——AOP( 面向切面编程)

    AOP 即 Aspect Oriented Program 面向切面编程 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 ...

  4. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  5. java aop面向切面编程

    最近一直在学java的spring boot,一直没有弄明白aop面向切面编程是什么意思.看到一篇文章写得很清楚,终于弄明白了,原来跟python的装饰器一样的效果.http://www.cnblog ...

  6. 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~

    简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...

  7. Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...

  8. aop面向切面编程的实现

    aop主要用于日志记录,跟踪,优化和监控 下面是来自慕课网学习的一些案例,复制黏贴就完事了,注意类和方法的位置 pom添加依赖: <dependency> <groupId>o ...

  9. AOP 面向切面编程, Attribute在项目中的应用

    一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...

随机推荐

  1. mysql的sql语句练习的2个网址

    sql语句练习: https://blog.csdn.net/mrbcy/article/details/68965271 完成. https://blog.csdn.net/flycat296/ar ...

  2. JS 数组间的操作

    JS 数组间的操作(交集,并集.差集) 以下是js数组之间常用的操作,如交集,并集.差集等. 迭代 each是一个集合迭代函数,可以将一个函数作为参数和一组可以选的参数.依次将集合的每一个元素和可选参 ...

  3. 【MyBatis】MyBatis Tomcat JNDI原理及源码分析

    一. Tomcat JNDI JNDI(java nameing and drectory interface),是一组在Java应用中访问命名和服务的API,所谓命名服务,即将对象和名称联系起来,使 ...

  4. 获得Dictionary所有key和value值

    Dictionary<string, string> dc = new Dictionary<string, string>(); dc.Add("code" ...

  5. 洛谷 P1708 天然气井 题解

    https://www.luogu.org/problemnew/show/P1708 这道题还是比较好的. 读完题目我们先想想如何计算某个天然气井($x_1,y_1$)和中转站($a_1,b_1$) ...

  6. L2-2 社交集群 (25 分)(一个写挫的并查集)

    题目: 思路: 就是一个并查集的裸题,不过在数据查找方面可能不好处理,暴力完全可以解决这个问题啊!! #include <bits/stdc++.h> #include <cstdi ...

  7. HTML元素的基本特性

    1,Disabled 特性: //Disabled 设置元素不可用: $(this).attr("disabled","disabled") //移除push元 ...

  8. CI 安装时目录的安全处理

    如果你想通过隐藏 CodeIgniter 的文件位置来增加安全性,你可以将 system 和 application 目录修改为其他的名字,然后打开主目录下的 index.php 文件将 $syste ...

  9. JS获取所有LI中第三个<SPAN>

  10. nmon分析与详解

    1.命令安装 1.查看liunx版本版本x86_64_14i 目录:cd /nmon/logs/ 版本x86_64_14i [root@localhost u06]# cd / [root@local ...