Spring面向切面 --- AspectJ --- 简单使用

Spring面向切面 --- AspectJ --- 简单使用

昨天回复说说的时候突然写下了下面的一段话:分享一下:

<!--*******************************************

其实经过的记忆是可以进行道德化的篡改的,
就像夏目漱石的《我是猫》;
但是不管怎么改,真正的事实是由每一个人的碎片拼起来的;
经济学里计算成本的是在计算将来的成本而不是过去的成本,
就像动漫《未来日记》一样;
过去发生的事情总是在影响着将来,
但是过去发生的事情却不能充当将来下一个操作符的影响要素。
********************************************-->

面向切面编程用到了动态代理,感兴趣的读者可以参考我的日志:

http://www.cnblogs.com/kodoyang/p/DesignPattern_DynamicProxy.html

1.AspectJ - AOP
面向切面编程是面向对象的一个补充

在保存用户前添加一个日志,再加上时刻的记录。总之,就是方法前后加一点业务逻辑

新建资源库:
Preference>Java>BuildPath>UserLibraries,AddLibrary>UserLibrary

/Spring_AOP/src/yuki/spring/aop/imitate/UserService.java

package yuki.spring.aop.imitate;

public interface UserService {

    void save();
}

/Spring_AOP/src/yuki/spring/aop/imitate/UserServiceImpl.java

package yuki.spring.aop.imitate;

public class UserServiceImpl implements UserService{

    public void save(){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/yuki/spring/aop/imitate/Intercepter.java

package yuki.spring.aop.imitate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public abstract class Intercepter implements InvocationHandler {

    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }

    protected abstract void beforeMethod();
    protected abstract void afterMethod();

    @Override
    public Object invoke(Object proxy, Method m, Object[] args)
            throws Throwable {
        beforeMethod();
        m.invoke(target, args);
        afterMethod();
        return null;
    }

}

/Spring_AOP/src/yuki/spring/aop/imitate/LogIntercepter.java

package yuki.spring.aop.imitate;

public class LogIntercepter extends Intercepter {

    @Override
    public void beforeMethod() {
        System.out.println("log start...");
    }

    @Override
    protected void afterMethod() {
        System.out.println("log end...");
    }

}

/Spring_AOP/src/yuki/spring/aop/imitate/TimeIntercepter.java

package yuki.spring.aop.imitate;

public class TimeIntercepter extends Intercepter {

    @Override
    protected void beforeMethod() {
        System.out.println("start:" + System.currentTimeMillis());
    }

    @Override
    protected void afterMethod() {
        System.out.println("end:" + System.currentTimeMillis());
    }

}

/Spring_AOP/src/yuki/spring/aop/imitate/ProxyTest.java

package yuki.spring.aop.imitate;

import java.lang.reflect.Proxy;

public class ProxyTest {

    public static void main(String[] args) {
        UserService service = new UserServiceImpl();

        Intercepter[] intercepters = {new LogIntercepter(), new TimeIntercepter()};
        for(Intercepter intercepter : intercepters){
            intercepter.setTarget(service);
            service = (UserService) Proxy.newProxyInstance(
                    service.getClass().getClassLoader(),
                    service.getClass().getInterfaces(), intercepter);
        }

        service.save();

    }

}

上面的程序中,两个类继承了实现InvocationHandler接口的抽象类,

也可以说是间接地实现了InvocationHandler接口;

声明为UserService接口类型的service,

在循环中每一次接收Proxy.newProxyInstance方法的计算结果后就会改变它指向的对象。

运行结果如下:

start:1409496143248
log start...
user saved...
log end...
end:1409496143250

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

注解的方式实现AOP使用的是aspectj,aspectj是专门用来产生动态代理的一个框架
可以使用aspectj注解的方式实现spring的AOP,把这个逻辑织入到原来的逻辑里面去

引入jar:aspectjrt.jar、aspectj-weaver.jar:http://www.java2s.com/Code/Jar/a/aspectj.htm

在类上添加注解 @Aspect和 @Component,在方法上添加注解 @Before
切入点语法 @Before("execution(public void yuki.spring.aop.annotation"
+ ".UserServiceImpl.save(yuki.spring.aop.annotation.User))")
引入jar:aopalliance-.jar:http://www.java2s.com/Code/Jar/a/Downloadaopalliancejar.htm
@Component要加在对应的实现类上,因为getBean后要获取这个对象

/Spring_AOP/src/yuki/spring/aop/annotation/User.java

package yuki.spring.aop.annotation;

public class User {

}

/Spring_AOP/src/yuki/spring/aop/annotation/UserService.java

package yuki.spring.aop.annotation;

public interface UserService {

    void save(User user);
}

/Spring_AOP/src/yuki/spring/aop/annotation/UserServiceImpl.java

package yuki.spring.aop.annotation;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserServiceImpl implements UserService{

    public void save(User user){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/annotation.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd ">

    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.annotation"></context:component-scan>

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

/Spring_AOP/src/yuki/spring/aop/annotation/LogIntercepter.java

package yuki.spring.aop.annotation;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogIntercepter {

    @Before("execution(public void yuki.spring.aop.annotation"
            + ".UserServiceImpl.save(yuki.spring.aop.annotation.User))")
    public void beforeMethod() {
        System.out.println("method start...");
    }

}

/Spring_AOP/src/yuki/spring/aop/annotation/TimeIntercepter.java

package yuki.spring.aop.annotation;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TimeIntercepter {

    @Before("execution("
            + "public * yuki.spring.aop.annotation..*.*(..)"
            + ")")
    public void beforeMethod() {
        System.out.println("before:" + System.currentTimeMillis());
    }

    @AfterReturning("execution( public * yuki.spring.aop.annotation..*.*(..) )")
    public void afterReturningMethod() {
        System.out.println("afterReturning:" + System.currentTimeMillis());
    }
}

/Spring_AOP/src/yuki/spring/aop/annotation/PointcutIntercepter.java

package yuki.spring.aop.annotation;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class PointcutIntercepter {

    @Pointcut("execution( public * yuki.spring.aop.annotation..*.*(..) )")
    public void myMethod() {}

    @Before("myMethod()")
    public void beforeMethod() {
        System.out.println("PointcutIntercepter::before");
    }

    @AfterReturning("myMethod()")
    public void afterReturningMethod() {
        System.out.println("PointcutIntercepter::afterReturning");
    }
}

/Spring_AOP/src/yuki/spring/aop/annotation/UserServiceTest.java

package yuki.spring.aop.annotation;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    @Test
    public void testSave() {

        @SuppressWarnings("resource")
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("annotation.xml");
        UserService service = (UserService) context.getBean("userService");
        service.save(new User());
        context.destroy();
    }

}

运行结果如下:

八月 31, 2014 10:59:10 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org[email protected]1637f22: startup date [Sun Aug 31 22:59:10 CST 2014]; root of context hierarchy
八月 31, 2014 10:59:10 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [annotation.xml]
method start...
PointcutIntercepter::before
before:1409497152268
user saved...
afterReturning:1409497152268
PointcutIntercepter::afterReturning
八月 31, 2014 10:59:12 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org[email protected]1637f22: startup date [Sun Aug 31 22:59:10 CST 2014]; root of context hierarchy

术语解释:
JoinPoint:连接点、切入点,在哪里把逻辑加进区
PointCut:JoinPoint的集合,可以一次性定义好多切入点
Aspect:切面,切面类加进去的逻辑可以认为是一个切面
Advice:在这个点上建议怎么办,比如 @Before
Target:被织入逻辑的被代理对象
Weave:织入

2.切面和通知
切入点:
// the execution of any public method:
execution(public * *(..))
// the execution of any method with a name beginning with "set":
execution(* set*(..))
// the execution of any method defined by the AccountService interface:
execution(* com.xyz.service.AccountService.*(..))
// the execution of any method defined in the service package:
execution(* com.xyz.service..(..))
// the execution of any method defined in the service package or a sub-package:
execution(* com.xyz.service..*.*(..))
spring也定义了自己的织入点语法,但是我们只要用AspectJ的语法就可以了

通知:
Before、AfterReturn、AfterThrowing、After(意思是finally)
Around:在ProceedingJoinPoint.proceed()前后加逻辑

如果织入点表达式相同,可以定义Pointcut
定义方法名接收织入点表达式的值,使用时 @AfterReturning("pointcut()")

/Spring_AOP/src/yuki/spring/aop/pointcut/User.java

package yuki.spring.aop.pointcut;

public class User {

}

/Spring_AOP/src/yuki/spring/aop/pointcut/UserService.java

package yuki.spring.aop.pointcut;

public interface UserService {

    void save(User user);
}

/Spring_AOP/src/yuki/spring/aop/pointcut/UserServiceImpl.java

package yuki.spring.aop.pointcut;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserServiceImpl implements UserService{

    public void save(User user){
        System.out.println("user saved...");
        //throw new RuntimeException("exception...");
    }
}

/Spring_AOP/src/yuki/spring/aop/pointcut/TransactionAspect.java

package yuki.spring.aop.pointcut;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TransactionAspect {

    @Pointcut("execution( public * yuki.spring.aop.pointcut..*.*(..) )")
    public void pointcut(){}

    @Before("pointcut()")
    public void before(){
        System.out.println("before");
    }
    @AfterReturning("pointcut()")
    public void afterReturning(){
        System.out.println("afterReturning");
    }
    @AfterThrowing("pointcut()")
    public void afterThrowing(){
        System.out.println("afterThrowing");
    }

    @Around("pointcut()")
    public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("method around start...");
        pjp.proceed();
        System.out.println("method around end...");
    }

}

/Spring_AOP/src/pointcut.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd ">

    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.pointcut"></context:component-scan>

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

/Spring_AOP/src/yuki/spring/aop/pointcut/UserServiceTest.java

package yuki.spring.aop.pointcut;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    @Test
    public void testSave() {

        @SuppressWarnings("resource")
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("pointcut.xml");
        UserService service = (UserService) context.getBean("userService");
        service.save(new User());
        context.destroy();
    }

}

运行结果如下:

八月 31, 2014 11:09:22 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org[email protected]1637f22: startup date [Sun Aug 31 23:09:22 CST 2014]; root of context hierarchy
八月 31, 2014 11:09:22 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [pointcut.xml]
method around start...
before
user saved...
method around end...
afterReturning
八月 31, 2014 11:09:24 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org[email protected]1637f22: startup date [Sun Aug 31 23:09:22 CST 2014]; root of context hierarchy

可以实现声明式的异常管理,
struts2已经实现了声明式的异常管理,这里略过通知执行的先后顺序

3.cglib
如果被代理的类实现了接口, 就会使用JDK自带的Proxy和InvocationHandler来实现代理
当被代理的类没有实现接口, 它会用cglib直接操作二进制码的形式来产生代理的代码
引入jar:cglib-2.2.jar:http://www.java2s.com/Code/Jar/c/Downloadcglib22jar.htm

/Spring_AOP/src/yuki/spring/aop/cglib/UserService.java

package yuki.spring.aop.cglib;

import org.springframework.stereotype.Component;

@Component
public class UserService {

    public void save(){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/yuki/spring/aop/cglib/CglibAspect.java

package yuki.spring.aop.cglib;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class CglibAspect {

    @Pointcut("execution( public * yuki.spring.aop.cglib..*.*(..) )")
    public void pointcut(){}

    @Around("pointcut()")
    public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("method around start...");
        pjp.proceed();
        System.out.println("method around end...");
    }

}

/Spring_AOP/src/cglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd ">

    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.cglib"></context:component-scan>

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

/Spring_AOP/src/yuki/spring/aop/cglib/UserServiceTest.java

package yuki.spring.aop.cglib;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    @Test
    public void testSave() {

        @SuppressWarnings("resource")
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("cglib.xml");
        UserService service = (UserService) context.getBean("userService");
        System.out.println(service.getClass());
        service.save();
        context.destroy();
    }

}

运行结果如下:

八月 31, 2014 11:14:17 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org[email protected]1637f22: startup date [Sun Aug 31 23:14:17 CST 2014]; root of context hierarchy
八月 31, 2014 11:14:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [cglib.xml]
class yuki.spring.aop.cglib.UserService$$EnhancerBySpringCGLIB$$b8ea6837
method around start...
user saved...
method around end...
八月 31, 2014 11:14:19 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org[email protected]1637f22: startup date [Sun Aug 31 23:14:17 CST 2014]; root of context hierarchy

4.xml:AOP
pointcut可以声明在aspect的里面或外面

eclipse:从源码视图切换到设计视图

在执行UserService.save()时,发现符合配置的切入点表达式
对应的是LogAspect.before(),于是先执行before,然后save()
可以直接指定pointcut,也可以在外部指定然后再引用它
如果使用第三方类的切面类逻辑,那么就必须要使用xml配置的方式

/Spring_AOP/src/yuki/spring/aop/xml/UserService.java

package yuki.spring.aop.xml;

import org.springframework.stereotype.Component;

@Component("userService")
public class UserService {

    public void save(){
        System.out.println("user saved...");
    }
}

/Spring_AOP/src/yuki/spring/aop/xml/LogAspect.java

package yuki.spring.aop.xml;

public class LogAspect {

    public void before() {
        System.out.println("method start...");
    }

}

/Spring_AOP/src/xml.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/aop
                        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd ">

    <context:annotation-config></context:annotation-config>
    <context:component-scan base-package="yuki.spring.aop.xml"></context:component-scan>

    <bean id="logAspect" class="yuki.spring.aop.xml.LogAspect"></bean>
    <!--
    <aop:config>
        <aop:pointcut id="servicePointcut"
                expression="execution( public * yuki.spring.aop.xml..*.*(..) )" />
        <aop:aspect id="logAspect" ref="logAspect">
            <aop:before method="before" pointcut-ref="servicePointcut"/>
        </aop:aspect>
    </aop:config>
     -->

    <aop:config>
        <aop:aspect id="logAspect" ref="logAspect">
            <aop:before method="before"
                    pointcut="execution( public * yuki.spring.aop.xml..*.*(..) )"/>
        </aop:aspect>
    </aop:config>

</beans>

/Spring_AOP/src/yuki/spring/aop/xml/UserServiceTest.java

package yuki.spring.aop.xml;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserServiceTest {

    @Test
    public void testSave() {

        @SuppressWarnings("resource")
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("xml.xml");
        UserService service = (UserService) context.getBean("userService");
        service.save();
        context.destroy();
    }

}

运行结果如下:

八月 31, 2014 11:19:01 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org[email protected]1637f22: startup date [Sun Aug 31 23:19:01 CST 2014]; root of context hierarchy
八月 31, 2014 11:19:01 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [xml.xml]
method start...
user saved...
八月 31, 2014 11:19:02 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org[email protected]1637f22: startup date [Sun Aug 31 23:19:01 CST 2014]; root of context hierarchy

5.tomcat debug的热部署
在tomcat的jdk虚拟机参数中添加
-Dcom.sun.management.jmxremote=true

如果修改配置文件,使用了自定义标签的jsp页面,修改了注解,等等情况:还是要重启服务器的

在方法内部修改代码,不用重启服务器,这已经是很大的便捷了,

有兴趣的小伙伴们去研究功能更强大的热部署吧。。。。

目录结构:

本文参考了[尚学堂马士兵_Spring_AOP]的公开课程

更多好文请关注:http://www.cnblogs.com/kodoyang/

>*_*<

kongdongyang

2014/8/31

时间: 2024-12-25 18:10:47

Spring面向切面 --- AspectJ --- 简单使用的相关文章

Spring面向切面编程(二)简单AOP实例

简单实现一个用户登陆的功能,在用户登陆之前进行日志打印,用户登陆之后进行登陆成功日志打印. Maven添加Spring jar spring面向切面编程(一)AOP术语 添加Spring AOP的jar 参考:Maven添加Spring jar 还需添加: 创建User类: package com.user; public class User { private String username; private String password; public String getUsernam

Spring 面向切面编程(AOP)

Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of Control – IOC) 理解依赖注入(DI – Dependency Injection) Bean XML 配置(1)- 通过XML配置加载Bean Bean XML 配置(2)- Bean作用域与生命周期回调方法配置 Bean XML 配置(3)- 依赖注入配置 Bean XML 配置(

Spring面向切面编程

  1.面向切面编程(AOP)的概念:把项目中需要在多处用到的功能,比如日志.安全和事物等集中到一个类中处理,而不用在每个需要用到该功能的地方显式调用.   2.术语解释:        横切关注点:分布应用于多处的功能        切面:横切关注点可以被模块化为一个类,这个类被称为一个切面        通知(advice):切面要完成的工作.Spring的通知有5种类型:before.after.after-returning.after-throwing和around这五种类型.    

spring面向切面aop拦截器

spring中有很多概念和名词,其中有一些名字不同,但是从功能上来看总感觉是那么的相似,比如过滤器.拦截器.aop等. 过滤器filter.spring mvc拦截器Interceptor .面向切面编程aop,实际上都具有一定的拦截作用,都是拦截住某一个面,然后进行一定的处理. 在这里主要想着手的是aop,至于他们的比较,我想等三个都一一了解完了再说,因此这里便不做过多的比较. 在我目前的项目实践中,只在一个地方手动显示的使用了aop,那便是日志管理中对部分重要操作的记录. 据我目前所知,ao

spring面向切面编程示例(xml配置形式[email&#160;protected]注解形式)

一.xml配置形式 1.在Spring配置文件中增加面向切面配置当调用com.activemq.service.impl.ConsumerServiceImpl接口实现类的任意方法时执行切面类中的方法. 2.写切面类 注意:1)不能对web层(比如:com.activemq.action.ConsumerController)做代理插入操作,亲测无效.(之前认为对web层进行切面处理无效,其实不是,无效的原因在于切面配置所在的文件,如果是spring-mvc.xml(Springmvc的配置文件

[Spring] 面向切面

一.概述 按照软件重构思想的理念,如果多个类中出现相同的代码,应该考虑定义共同的抽象类.但并非所有情况下上述方法都是可行的,有时我们无法通过父类的方式消除重复性的横切代码,因为这些横切逻辑依附在业务类方法的流程中,不能转移到其他地方去. 面向切面编程(AOP)通过横向抽取机制为这类无法通过纵向继承进行抽象的重复性代码提供了解决方案.此前需要了解一些AOP概念 连接点(Joinpoint):程序执行的某个特定位置,如类初始化前后.方法调用前后等,Spring仅支持方法的连接点. 切点(Pointc

详解Spring面向切面编程(AOP)三种实现

一.什么是AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.OOP引入封装.继承.多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合.不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能.日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性.异常处理和透明的持续性也都是如此,这

Spring面向切面编程(AOP)

1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即实例化:spring加载完成,立即创建对象) scope:属性 singleton:默认值为单例,默认也是立即加载,在加载完成spring容器的时候,bean对象已经创建完成 prototype:多例的,默认懒加载,spring容器加载完成的时候,不会创建bean的对象,只有从容器获得bean对象的

Spring面向切面(AOP)

AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志.事务.权限等,Struts2的拦截器设计就是基于AOP的思想. AOP的基本概念 Aspect(切面):通常是一个类,里面可以定义切入点和通知 JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用. Advice(通知):AOP在特定的切入点上执行的增强处理,有before.after.afterReturning.afterThrowing.around Pointcut(切入点):AOP框架创