`

spring日记(四):AOP基础

阅读更多

AOP的实现者:AspectJ、JBoss AOP、Spring AOP,其中AspectJ提供语言级别的AOP实现,有一个专门的编译器生成遵守Java字节编码规范的Class文件。在Spring中,可以无缝集成Spring AOP、IoC、AspectJ。

Spring AOP使用了两种代理机制:一种是基于JDK的动态代理,另一种是基于CGLib的动态代理,之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的代理,而不支持类的代理。

》JDK动态代理实例:

package com.springzoo.proxy;
 
public interface ForumService {
    void removeTopic(int topicId);
    void removeForum(int forumId);
}

 

package com.springzoo.proxy;
 
public class ForumServiceImpl implements ForumService {
 
    public void removeTopic(int topicId) {
        System.out.println("模拟删除Topic记录:"+topicId);
        try {
            Thread.currentThread().sleep(20);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
 
    public void removeForum(int forumId) {
        System.out.println("模拟删除Forum记录:"+forumId);
        try {
            Thread.currentThread().sleep(40);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }       
    }
}

 

package com.springzoo.proxy;
 
public class PerformanceMonitor {
    private static ThreadLocal<MethodPerformace> performaceRecord = new ThreadLocal<MethodPerformace>();
    public static void begin(String method) {
        System.out.println("begin monitor...");
        MethodPerformace mp = performaceRecord.get();
        if(mp == null){
            mp = new MethodPerformace(method);
            performaceRecord.set(mp);
        }else{
            mp.reset(method);   
        }
    }
    public static void end() {
        System.out.println("end monitor...");
        MethodPerformace mp = performaceRecord.get();
        mp.printPerformace();
    }
}

 

package com.springzoo.proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class PerformaceHandler implements InvocationHandler {
    private Object target;
    public PerformaceHandler(Object target){
        this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        PerformanceMonitor.begin(target.getClass().getName()+"."+ method.getName());
        Object obj = method.invoke(target, args);
        PerformanceMonitor.end();
        return obj;
    }
}

 

 

 

最后测试下:

package com.springzoo.proxy;
 
public class TestForumService {
    public static void main(String[] args) {
        // 使用JDK动态代理
//      ForumService target = new ForumServiceImpl();
//      PerformaceHandler handler = new PerformaceHandler(target);
//      ForumService proxy = (ForumService) Proxy.newProxyInstance(target
//              .getClass().getClassLoader(),
//              target.getClass().getInterfaces(), handler);
//      proxy.removeForum(10);
//      proxy.removeTopic(1012);
         
        //使用CGLib动态代理
        CglibProxy proxy = new CglibProxy();
        ForumService forumService = (ForumService)proxy.getProxy(ForumServiceImpl.class);
        forumService.removeForum(10);
        forumService.removeTopic(1023);
         
    }
}

 

以上的手动编写AOP逻辑和植入非常的不方便,而spring AOP就是要解决这个问题。spring AOP通过Pointcut指定在哪些类的哪些方法上织入横切逻辑,通过Advice描述横切逻辑和方法的织入方位(方法前、方法后、方法前后,跑出异常时)。此外,spring通过Advisor切面将Pointcut和Advice两者组装起来。有了Advisor的信息,spring就可以利用JDK或者CGLib的动态代理技术采用统一的方式为目标Bean创建织入切面的代理对象了。

动态代理性能:CGLib的代理对象性能是JDK的10倍,但是创建时间是JDK的8倍,因此对于singleton的对象适合用CGLib,而其他的情况适合用JDK动态代理。注意,CGLib由于采用动态创建子类方式生产代理对象,所以不能对目标类中的final方法进行代理。

》Introduction,引介增强

引介增强可以为目标类创建新的方法和属性,所以其连接点是类级别,通过引介增强我们可以为目标类添加一个接口的实现,通过引介增强我们可以为目标类创建实现某接口的代理。继承DelegatingIntroductionInterceptor即可,覆盖其中的invoke方法。

先定义一个接口类:

package com.springzoo.introduce;
 
public interface Monitorable {
   void setMonitorActive(boolean active);
}

然后自定义Introduction:

package com.springzoo.introduce;
 
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
 
public class ControllablePerformaceMonitor extends DelegatingIntroductionInterceptor
        implements Monitorable{
    private ThreadLocal<Boolean> monitorStatusMap = new ThreadLocal<Boolean>();
 
    public void setMonitorActive(boolean active) {
        monitorStatusMap.set(active);
    }
 
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object obj = null;
        if (monitorStatusMap.get() != null && monitorStatusMap.get()) {
            PerformanceMonitor.begin(mi.getClass().getName() + "."
                    + mi.getMethod().getName());
            obj = super.invoke(mi);
            PerformanceMonitor.end();
        } else {
            obj = super.invoke(mi);
        }
        return obj;
    }
}
 

接下来在spring中配置Introduction:

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
    <bean id="pmonitor" class="com.springzoo.introduce.ControllablePerformaceMonitor" />
    <bean id="forumServiceTarget" class="com.springzoo.introduce.ForumService" />
    <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"
        p:interfaces="com.springzoo.introduce.Monitorable"
        p:target-ref="forumServiceTarget"
        p:interceptorNames="pmonitor"
        p:proxyTargetClass="true" />
</beans>

注意:必须指定引介增强所实现的接口,p:inaterfaces,其次由于只能通过为目标类创建子类方式生产引介增强代理,所以必须将proxyTargetClass设为true。还有就是我们没有对ControllerPerformanceMonitor进行线程安全的特殊处理,就必须将singleton属性设为true让ProxyFactoryBean产生prototype的代理,这样会带来严重的性能问题,因为CGLib创建动态代理的性能很低,所以加了个TreadLocal,那么就可以了。

》创建切面Advisor

我们再次给出spring AOP如何定位连接点:

增强Advice提供了连接点方位信息:如织入方法前、后等,而切点进一步描述织入到哪些类的哪些方法上。

spring通过org.springframework.aop.Pointcut接口描述切点,Pointcut由ClassFilter和MethodMatcher构成。

 

本人博客已搬家,新地址为:http://yidao620c.github.io/

分享到:
评论

相关推荐

    SpringAOP的日志拦截示例

    &lt;aop:advisor advice-ref="logInterceptor" pointcut-ref="logPointcut" /&gt; &lt;/aop:config&gt; &lt;!-- 其他配置... --&gt; ``` 这里,我们定义了一个切入点(pointcut),它匹配`com.example.service`包下所有类的所有方法...

    用ssm(spring+springmvc+mybatis)开发的的一个简单的个人日记系统(本人的javaee的课程设计)

    1. **Spring**:Spring是一个全面的企业级应用框架,它提供了依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)等功能。在本项目中,Spring用于管理各个组件的生命周期,...

    计算机实习日记15篇

    Spring框架提供了AOP功能,作者在日记中提到了AOP的使用场景和优点。 关于Hibernate框架 Hibernate是一个对象关系映射(ORM)框架,用于将Java对象映射到关系数据库中。作者在日记中提到了Hibernate的使用场景和...

    社交网站后端项目开发日记(一)(csdn)————程序.pdf

    项目的pom.xml文件中包含了初始依赖,包括spring-boot-starter-aop、spring-boot-starter-thymeleaf、spring-boot-starter-web、spring-boot-devtools、spring-boot-starter-test等。 四、SpringBoot基础知识 ...

    【整合汇编】2021年计算机实习日记四篇.docx

    【整合汇编】2021年计算机实习日记四篇主要涵盖了Java Web开发中的核心技术,包括Struts、Spring和Hibernate框架的使用,以及页设计和数据库管理的基础知识。以下是这些知识点的详细说明: 1. **Struts框架**: - ...

    Java 程序 日记本

    12. **Spring框架**:Spring的核心概念,依赖注入(DI),AOP(面向切面编程),以及Spring Boot的快速开发能力。 13. **数据库操作**:JDBC的使用,SQL语言的基础和进阶,事务的处理,以及数据库连接池的配置和...

    计算机毕业实习日记34篇..doc

    - **Spring**:提供IOC容器管理和AOP支持,简化业务逻辑层的开发。 - **Hibernate**:实现ORM功能,简化数据持久层的开发。 - **学习难点**: - **英语文档阅读**:大量的英文技术文档和官方指南增加了学习难度。...

    JAVAEE开发+MyBatis+Spring+SpringMVC+个人博客管理系统+用于发布日志和博客

    在本项目中,我们主要利用JavaEE开发技术,结合MyBatis、Spring和SpringMVC框架,构建一个个人博客管理系统,旨在实现博客和日记的发布、浏览及管理功能。以下将详细阐述这些关键技术及其在项目中的应用。 首先,...

    【整合汇编】2021年计算机实习日记四篇.pdf

    【整合汇编】2021年计算机实习日记四篇主要记录了实习生在不同阶段学习和实践计算机技术,特别是Java Web开发的相关经验。以下是其中涉及的主要知识点: 1. **Struts+Spring+Hibernate 框架**:这三个框架是Java ...

    spring+structs+Hibernate

    首先,Spring框架是Java企业级应用的核心框架,它提供了依赖注入(DI)和面向切面编程(AOP)等功能,极大地简化了应用的开发和测试。在SSH集成中,Spring主要负责管理整个应用的组件,包括Struts和Hibernate的实例...

    计算机实习日记四篇【精选汇编】.docx

    Spring提供了IOC(控制反转)和AOP(面向切面编程),用于对象管理和事务处理,增强了代码的可维护性和灵活性。Hibernate则是ORM(对象关系映射)框架,简化了Java程序与数据库之间的交互,避免了直接编写SQL语句,...

    九宫格日记(J2EE开发)

    Spring框架提供了依赖注入、AOP(面向切面编程)等功能,使得代码更易于维护和测试。 安全方面,我们需要考虑用户认证和授权。可以通过实现用户注册、登录功能,使用session或JWT(JSON Web Tokens)来管理用户会话...

    SSH日记程序整合

    可以使用Struts的拦截器或Spring的AOP来实现这一目标。 6. **异常处理**:为了提供良好的用户体验,需要定义全局的异常处理机制,捕获并处理可能出现的运行时错误,同时记录这些异常信息到日志中。 7. **性能优化*...

    实习日记34篇(我的实习日记)

    5. Spring 框架的应用:Spring 是一个提供了 IOC(控制反转)和 AOP(对向切面编程)的框架,能够实现对象和事务的集中管理。 6. Hibernate 框架的应用:Hibernate 是一个实现对象与关系映射的中间件,能够让编程...

    计算机java实习日记.docx

    - **Spring**:Spring框架提供了IoC(Inversion of Control,控制反转)和AOP(Aspect-Oriented Programming,面向切面编程),用于业务逻辑层,提供事务管理和对象管理。 - **Hibernate**:是一个ORM(Object-...

    计算机java实习日记.pdf

    1. **Java Web开发**:Java是一种广泛用于Web开发的编程语言,实习生在日记中提到了使用Java进行网站开发,这涉及到Java的基础语法、面向对象编程以及与Web相关的技术。 2. **Tomcat服务器**:Tomcat是一个开源的...

    【ssm项目源码】日记管理系统.zip

    【SSM项目源码】日记管理系统是一个基于Spring、SpringMVC和MyBatis三大主流Java技术框架构建的应用程序。这个项目旨在实现一个完整的日记管理平台,用户可以在这里记录、查看、编辑和删除他们的个人日记。下面我们...

    计算机实习日记四篇【精选汇编】.pdf

    - Spring 提供了控制反转(IOC)和依赖注入,实现对象管理,并引入了面向切面编程(AOP),增强了框架的扩展性和灵活性。 - Hibernate 是对象关系映射(ORM)框架,简化了数据库操作,通过封装JDBC,使得开发者...

    程序员实习日记,计算机专业实习日记.pdf

    2. **Spring**:Spring框架不仅提供了IOC(控制反转)和DI(依赖注入),使得对象间的依赖关系得以解耦,还支持AOP(面向切面编程),用于处理横切关注点,如事务管理。Spring还允许声明式事务管理,简化了事务处理...

Global site tag (gtag.js) - Google Analytics