spring之Aop面向切面

面向切面编程中的一些概念

1.1 代理模式

代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用

A. 抽象主题角色

声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以是使用代理主题

B. 代理主题(Proxy)角色:

代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主题控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯地将调用传递给真实主题对象。

C. 真实主题角色

定义了代理角色所代表地真实对象

1.1.1 JDK动态代理

JDK的动态代理必须具备四个条件:

目标接口

目标类

拦截器

代理类

总结:1、因为利用JDKProxy生成的代理类实现了接口,所以目标类中所有的方法在代理类中都有。

2、生成的代理类的所有的方法都拦截了目标类的所有的方法。而拦截器中invoke方法的内容正好就是代理类的各个方法的组成体。

3、利用JDKProxy方式必须有接口的存在。

4、invoke方法中的三个参数可以访问目标类的被调用方法的API、被调用方法的参数、被调用方法的返回类型。

1.1.2 CGLIB做代理

1、 CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。

2、 用CGlib生成代理类是目标类的子类。

3、 用CGlib生成 代理类不需要接口

4、 用CGLib生成的代理类重写了父类的各个方法。

5、 拦截器中的intercept方法内容正好就是代理类中的方法体

spring有两种代理方式:

1. 若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。

优点:因为有接口,所以使系统更加松耦合

缺点:为每一个目标类创建接口

2. 若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。

优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。

缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。

1.1.3 Spring的动态代理

1、 拦截器必须实现MethodInterceptor接口

2、 在spring中的配置

总结:不管采用JDK动态代理生成代理类还是采用CGLIB生成动态代理类。目标类中的所有方法都被拦截下来。而在哪个方法里做比如权限的判断、安全性的检查等一系列工做必须在拦截器中作相应的判断。但是这样的编程形式给程序的编写带来了一定的麻烦。

1、 在拦截器中控制哪些方法将被做权限判断、安全性检查等是一件比较困难的事情。

A. 采取这样的配置目标类只能是一个,所以如果用这种方法做权限控制,得写很多代理,这样给代码的书写造成了困难。

B. 每一个类中的每一个方法如果都有不同的权限(实际的系统往往都是这样的),在拦截器中的判断代码书写会很困难。

2、 这样的代码也会导致硬编码,也就是说我们必须在拦截器中写一些权限判断等事情,会导致拦截器中代码量的增大,造成维护的麻烦。

1.2 AOP编程

1.2.1概念:

A. Aspect(切面)

比如说事务、权限等,与业务逻辑没有关系的部分

B. joinpoint(连接点)

目标类的目标方法。(由客户端在调用的时候决定)

C. Pointcut(切入点)

所谓切入点是指我们要对那些拦截的方法的定义.

被纳入spring aop中的目标类的方法。

D. Advice(通知)

所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)

E. Target(目标对象):

代理的目标对象

F. Weaving(织入)

是指把切面应用到目标对象来创建新的代理对象的过程.切面在指定的连接点织入到目标对象


JDKProxy代理


SpringAop


目标对象


目标对象


拦截器类


切面


拦截器类中的方法


通知


被拦截到的目标类中方法的集合


切入点


在客户端调用的方法(目标类目标方法)


连接点


代理类


AOP代理


代理类的代理方法生成的过程


织入

通知根据拦截目标类中的目标方法的位置不一样可以分为:前置通知、后置通知、最终通知、环绕通知、异常通知

1.2.2 AOP实现的两种模式

1.2.2.1 xml形式

A. 前置通知

在spring配置文件中声明切面

在spring配置文件中声明目标类

定义切面、切入点、通知

注:见6.2.3.4

说明:

1、在切面类中,没有必要实现接口,但方法名称要与<aop:before method=”checkSecurity” 中的checkSecurity一样。

2、checkSecurity方法中通过JoinPoint参数可以获得目标类的目标方法名称、参数值等信息。

B. 后置通知

1、 没有特殊说明的地方和前置通知是一样的。

2、 在spring配置文件中

3、 在拦截器中的方法要和checkSecurity方法一样,有两个参数

JoinPoint   point    可以获得目标方法和参数值

Object      val    这里的名字要和returning=”val”中保持一致,指的是方法的返回值。

4、 returning=”val”时,通知里可以有返回参数,这个参数只能决定通知里能不能拿到方法的返回值,和客户端没有关系。

5、  在执行目标类的目标方法中遇到异常,则不执行后置通知。

C. 异常通知

1、 没有特殊说明的地方和前置通知一样

2、 在spring配置文件中

其中throwing指定了传递异常的参数名称

3、 在异常通知中(拦截器)中,必须是checkSecurity方法。方法中有两个参数

JoinPoint    point   可以获得方法的名称、参数

Throwable   ex    利用ex.getMessage()可以获得异常信息

D. 最终通知

1、 没有特殊说明,和前置通知的配置一样。

2、 在spring配置文件里:

说明:在最终通知中不受异常的影响。也就是说不论目标方法执行的过程中是否抛出异常,最终通知都将执行。

E. 环绕通知

1、 没有特殊说明和前置通知的配置保持一致。

2、 在spring文件中

3、 在环绕通知中,方法名称为checkSecurity。参数 类型 为ProceedingJoinPoint。

ProceedingJoinPoint的proceed方法相当于invoke方法,调用目标类的目标方法。ProceedingJoinPoint继承了JoinPoint类

4、  能在方法执行的前后加入额外的代码。

说明:

1.2.2.2Aop注解形式

A. 前置通知

注意:@Aspectj是按照类型匹配的。

B. 后置通知

C. 异常通知

D. 最终通知

E. 环绕通知

spring中使用aop的实例和配置文件

1、proxyBeanFactory:代理类创建bean工厂,之前的beanFactory就是一个容器,创建bean,管理bean而proxyBeanFactory就是一个创建代理对象的工厂,和其他javabean一样也有一些属性控制他的行为,下面列出常用的一些属性。

2、proxybeanFactory配置文件常用的属性:现在站在代理类的角度看的话可能更清晰

(1)target: 代理目标(被代理者),这个属性指定了你这个代理对象要代理的目标对象即被代理对象(委托者)

<beanid =""  class="">

<propertyname="target">

<ref bean="被代理的对象的id">

</property>

</bean>

//这样的话我们知道有这个被代理对象暴露出来了,我们可以直接定义在内部

<beanid="" class="">

<propertyname="target">

<beanclass="" />

</property>

</bean>

// 这样就不会被外部使用了,因为隐藏在了内部

(2)、proxyInterface: 这个属性指定了,从工厂中创建的bean要实现的接口

<beanid="" class="">

<propertyname="proxyInterface">

<value>impinterface</value>

</property>

</bean>

// 这样proxyBeanFactory就知道了创建的bean对象要实现impinterface 这个接口

(3)、interceptorName: interceptor(拦截机,妨碍着) 定义了一个应用到目标对象上的advisor或列表

// 提供多个接口来实现,使用list

<beanid="" class="">

<property  name="interceptorName">

<list>

<value>advisor1</value>

<value>advisor2</value>

<value>serviceTarget</value>

// 指定了被代理对象,但是还是使用 target属性来指定

</list>

</property>

</bean>

总结: 通过上面这三个属性的配置,很清晰的看到就是一个代理模式的实现,其中的target就是指定了被代理的对象,proxyInterface就是代理类要实现的接口,而interceptorName就是一个通知,或已被安全监测等拦截器,通过这三个属性的配置就可以实现代理,也就是 spring中说的aop

实例:实现前置通知,后置通知,以及环绕通知的实现

(1)、interface 代理类要实现的接口(proxyInterface)

package com.inspur.imp;

/**

*@author WHD

*2015-2-3

*/

public interface IStudent {

public  void  addStu(String name);

public void  addStuName(String name);

public void delStu();

}

(2)、目标类(target)

package com.inspur.imp;

/**

*@author WHD

*2015-2-3

*/

public class IStudentImp  implements IStudent{

@Override

public void addStu(String name) {

System.out.println("委托类执行 开始!");

// TODO Auto-generated method stub

if("".equals(name)){

System.out.println("名称为空");

}

if("whd".equals(name)){

System.out.println(" name  is"+name);

}

System.out.println("名称"+name);

}

@Override

public void addStuName(String name) {

// TODO Auto-generated method stub

System.out.println("add  name:"+name);

}

@Override

public void delStu() {

// TODO Auto-generated method stub

System.out.println("delete stu");

}

}

(3)、切面(切面中只定义了前置通知)

package com.inspur.imp;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

/**

*@author WHD

*2015-2-3

*/

// 和业务无关的这个类就是切面

public  class MethodBeforeImp  implements MethodBeforeAdvice {

@Override

//  这个方法就是通知

public void before(Method arg0, Object[] arg1, Object arg2)

throws Throwable {

// 获取目标类的名称,方法名称以及方法中的参数

// 方法名

String name1=arg0.getName();

//参数值

String name2=arg1[0].toString();

//类名

Object obj=arg2.getClass();

String name3=obj.toString();

if("whd".equals(name2)){

System.out.println("参数值"+name2);

}

System.out.println("before method"+"  方法名称:"+name1+"  参数值:"+name2+"  目标类:"+name3);

}

}

(4)、切面(切面中只定义了后置通知)

package com.inspur.imp;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

/**

*@author WHD

*2015-2-3

*/

// 和业务无关的这个类就是切面

public class AfterAdvice   implements AfterReturningAdvice {

@Override

//  这个方法就是通知

public void afterReturning(Object arg0, Method arg1, Object[] arg2,

Object arg3) throws Throwable {

// TODO Auto-generated method stub

//参数值

String  name=arg2[0].toString();

System.out.println("后置通知"+name);

}

}

(5)、环绕通知

package com.inspur.imp;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

/**

*@author WHD

*2015-2-3

*/

//和业务无关的这个类是切面

public class CompareInterceptor implements MethodInterceptor {

@Override

//  这个方法就是通知

public Object invoke(MethodInvocation arg0) throws Throwable {

// TODO Auto-generated method stub

Object  result=null;

String obj=arg0.getArguments().toString();

if("whd".equals(obj)){

result=arg0.proceed();

System.out.println("环绕方法");

}else{

System.out.println("环绕方法");

}

return result;

}

}

(6)、配置文件

<?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:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

<!--    目标对象  -->

<bean id="studentImp"  class="com.inspur.imp.IStudentImp">

</bean>

<!--  切面-前置通知(拦截器)   -->

<bean id="beforeAdvice"  class="com.inspur.imp.MethodBeforeImp"/>

<!--  切面-后置通知(拦截器)   -->

<bean  id="afterAdvice"   class="com.inspur.imp.AfterAdvice"/>

<!-- 
切面-环绕通知(拦截器)  -->

<bean id="compareInterceptor"  class="com.inspur.imp.CompareInterceptor" />

<!--  代理类   -->

<bean id="proxystudent"  class="org.springframework.aop.framework.ProxyFactoryBean">

<!--  代理类要实现的接口 -->

<property name="proxyInterfaces">

<value>com.inspur.imp.IStudent</value>

</property>

<!--切面(拦截器) -->

<property name="interceptorNames">

<list>

<value>beforeAdvice</value>

<value>afterAdvice</value>

<value>compareInterceptor</value>

</list>

</property>

<!-- 目标类 -->

<property name="target">

<ref bean="studentImp"/>

</property>

</bean>

</beans>

(7)、测试类

/**

*

*/

package com.test;

import java.util.List;

import java.util.Map;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.inspur.imp.IStudent;

import junit.framework.TestCase;

/**

*@author WHD

*2014-10-4

*/

public class TestDisk extends TestCase{

public  void  test(){

ApplicationContext  act= new ClassPathXmlApplicationContext("ApplicationContext.xml");

IStudent stu= (IStudent)act.getBean("proxystudent");

stu.addStu("whd");

}

}

实例:对指定的方法实现前置通知,后置通知,其实在实际中我们也是只对某一类进行方法进行拦截的,也就是静态切入点

(1)、抽象接口

package com.inspur.dao;

/**

*@author WHD

*2015-2-4

*/

public interface shopping {

public String buySomething(String type);

public String buyAnything(String type);

public String sellSomething(String type);

public String sellAnything(String type);

}

(2)、目标类

package com.inspur.dao;

/**

*@author WHD

*2015-2-4

*/

public class Shoppingimp implements shopping{

@Override

public String buySomething(String type) {

// TODO Auto-generated method stub

System.out.println("bysomethind"+ type);

return null;

}

@Override

public String buyAnything(String type) {

// TODO Auto-generated method stub

System.out.println("buyAnything"+ type);

return null;

}

@Override

public String sellSomething(String type) {

// TODO Auto-generated method stub

System.out.println("sellSomething"+ type);

return null;

}

@Override

public String sellAnything(String type) {

// TODO Auto-generated method stub

System.out.println("sellAnything"+ type);

return null;

}

}

(3)、切面(切面只定义了前置通知)

package com.inspur.dao;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

/**

*@author WHD

*2015-2-4

*/

//这个和业务无关的类就是一个切面

public class MethodBefore  implements MethodBeforeAdvice  {

@Override

// 切面中的方法,就是一个通知---前置通知

public void before(Method arg0, Object[] arg1, Object arg2)

throws Throwable {

// TODO Auto-generated method stub

String type=arg1[0].toString();

System.out.println("前置拦截器"+type);

}

}

(4)、配置文件

<?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:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

<!--目标类-->

<bean id="shoppingImpl"  class="com.inspur.dao.Shoppingimp">

</bean>

<!-- 切面(拦截器)--前置通知-->

<bean id="shoppingAdvise"  class="com.inspur.dao.MethodBefore">

</bean>

<!--  静态切入点  这里的class 说明是使用方法名称匹配来实现的,切入点就是一个规则 -->

<bean id="shoppingPointCutAdvisor"  class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

<!--   这个属性说明了对哪些方法进行拦截,也就是定义了拦截规则   -->

<property name="mappedNames">

<list>

<value>sellSomething</value>

<value>sellAnything</value>

</list>

</property>

<!--    织入切面的通知  -->

<property name="advice">

<ref  bean ="shoppingAdvise"/>

</property>

</bean>

<!-- 代理类 这个和上面一个不同,这里的interceptorNames这个属性的值为上面定义的切入点的id  -->

<bean id="StaticAdvisorTest"  class="org.springframework.aop.framework.ProxyFactoryBean">

<property  name="proxyInterfaces">

<value>com.inspur.dao.shopping</value>

</property>

<property name="interceptorNames">

<list>

<value>shoppingPointCutAdvisor</value>

</list>

</property>

<property name="target">

<ref bean="shoppingImpl"/>

</property>

</bean>

</beans>

(5)、测试类

/**

*

*/

package com.test;

import java.util.List;

import java.util.Map;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.inspur.dao.shopping;

import junit.framework.TestCase;

/**

*@author WHD

*2014-10-4

*/

public class TestDisk extends TestCase{

public void testStatic(){

ApplicationContext  act= new ClassPathXmlApplicationContext("ApplicationContext.xml");

shopping stu= (shopping)act.getBean("StaticAdvisorTest");

stu.buyAnything("to buy antthing");

stu.sellAnything("want sell angthing");

stu.sellSomething("sellsomething");

}

}

动态切入点

(1)、接口

package com.inspur.service;

/**

*@author WHD

*2015-2-4

*/

public interface Implement {

void  test();

}

(2)、目标类

package com.inspur.service;

/**

*@author WHD

*2015-2-4

*/

public class Target  implements Implement{

@Override

public void test() {

// TODO Auto-generated method stub

System.out.println("目标类");

}

}

(3)、切面的前置通知

package com.inspur.service;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

/**

*@author WHD

*2015-2-4

*/

public class Before implements MethodBeforeAdvice {

@Override

public void before(Method arg0, Object[] arg1, Object arg2)

throws Throwable {

// TODO Auto-generated method stub

System.out.println("前置通知");

}

}

(4)、动态切入点配置类,只有通过这个类调用目标类的方法拦截器才起作用

package com.inspur.service;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

/**

*@author WHD

*2015-2-4

*/

// 当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。

//换句话说,就是这个类可以直接获取spring配置文件中,所有有引用到的bean对象。

public class Argument  implements ApplicationContextAware {

//  代理类型

private Implement impl;

@Override

public void setApplicationContext(ApplicationContext context)

throws BeansException {

// TODO Auto-generated method stub

impl = (Implement)context.getBean( "aop");

}

public void test() {

System.out.println( "Argument.test()");

impl.test();

}

public void test2(Implement i) {

i.test();

}

}

(5)、配置文件

<?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:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

<!-- 动态切入点 -->

<bean id="arg" class="com.inspur.service.Argument" />

<!-- 这个类中配置切入点,也就是调用这个的构造函数中的那个类的方法拦截器才会起作用 -->

<bean id="dponintcut" class="org.springframework.aop.support.ControlFlowPointcut">

<constructor-arg>

<value>com.inspur.service.Argument</value>

</constructor-arg>

</bean>

<!-- 和之前一样 定义通知(拦截器),不同的是这里是给属性赋值-->

<bean id="advice" class="org.springframework.aop.support.DefaultPointcutAdvisor">

<property name="advice">

<bean class="com.inspur.service.Before" />

</property>

<property name="pointcut">

<ref bean="dponintcut"/>

</property>

</bean>

<!-- 代理类  -->

<bean id="aop" class="org.springframework.aop.framework.ProxyFactoryBean">

<!-- 要实现的接口-->

<property name="proxyInterfaces">

<list>

<value>com.inspur.service.Implement</value>

</list>

</property>

<!-- 通知-->

<property name="interceptorNames">

<list>

<value>advice</value>

</list>

</property>

<!-- 目标类 -->

<property name="target">

<bean class="com.inspur.service.Target" />

</property>

</bean>

</beans>

(6)、测试类

/**

*

*/

package com.test;

import java.util.List;

import java.util.Map;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.inspur.service.Argument;

import com.inspur.service.Implement;

import junit.framework.TestCase;

public  void  test(){

ApplicationContext context = new ClassPathXmlApplicationContext( "ApplicationContext.xml");

//  获取动态切入点类

Argument arg = (Argument)context.getBean( "arg");

//  对于这个调用前置通起作用

arg.test();

System.out.println( "----------------");

//  代理类

Implement impl = (Implement)context.getBean( "aop");

//  对于这个调用不起作用

impl.test();

System.out.println( "----------------");

//  对于这个调用前置通起作用

arg.test2( impl);

}

}

测试结果:

(7)、从这个测试结果我们看到,通过Argument    类调用的方法都调用前置通知,而没有通过他的则不会调用前置通知,所以这个Argument 就是一个切入点。

对有些内容还是有点模糊,如果有写错的希望各位指正,谢谢!

时间: 2024-10-11 18:14:50

spring之Aop面向切面的相关文章

spring入门-AOP 面向切面编程

AOP 面向切面编程 在日常开发中最后将业务逻辑定义在一个专门的service包下,而实现定义在service包下的impl包中, 服务接口以IXXXService形式,而服务实现就是XXXService,这就是规约设计 步骤: 1.E:\Users\WorkSpaces\KmwalletApp\spring\aop\test\HelloWorldService.java 继承(implements)xx接口 2.E:\Users\WorkSpaces\KmwalletApp\spring\ao

Spring:AOP, 面向切面编程

AOP概述 什么是AOP, 面向切面编程 AOP为Aspect Oriented Programming的缩写, 意为:面向切面编程, 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP是OOP的延续, 是函数式编程的一种衍生范型. 利用AOP可以对业务逻辑的各个部分进行隔离, 从而使得业务逻辑各部分之间的耦合度降低, 提高程序的可重用性, 同时提高了开发的效率. - 传统开发模型: 纵向的编程.  面向切面编程: 纵横配合的编程. AOP的作用及优势 作用: 在程序运行期

Spring的AOP面向切面编程

什么是AOP? 1.AOP概念介绍 所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程. 功能: 让关注点代码与业务代码分离! 关注点: 重复代码就叫做关注点: 业务代码: 核心业务的代码 业务代码与关注点代码分离,好处? --> 关注点代码写一次即可: -->开发者只需要关注核心业务: -->运行时期,执行核心业务代码时候动态植入关注点代码: [代理] 如何分离? 过程式/对象式/代理模式分离 AOP的好处是可以动态地添加和删除在切面上的逻辑而不

Spring的AOP面向切面原理,IOC控制反转【也叫DI依赖注入】原理

AOP即面向切面:AOP技术利用一种称为“横切”的技术,解剖封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,这样就能减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性.AOP把软件系统分为两个部分:核心关注点和横切关注点.业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点.横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似.比如权限认证.日志.事务处理.简言:把java对象进行横切: 即在对像执行功能时进行了插入:设置了

Spring之AOP(面向切面编程)_入门Demo

软件152 刘安民 AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现. 实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行:二是采用静态植入的方式,引入特定的语法创建"方面",从而使得编译器可以在编译期间织入有关"方面"的代

java的动态代理的两种方式和spring的aop面向切面编程的对比

java动态代理的两种方式 使用动态代理的好处:可以进行类的功能的加强,同时减少耦合和代码的冗余,耦合的意思是不用吧加强的部分写到各个实现类里面,冗余的意思是如果对每个实现类加强的部分是一样的,通过一个代理类即可实现 基于jdk的动态代理 通过jdk中自带的Proxy类进行动态的代理,Proxy创建动态代理对象的时候要传入三个参数,第一个是classloader,第二个是interfaces,第三个是代理类实现的方法 要求:代理的是一个接口,必须至少有一个实现类 创建接口的代码: /** * a

【spring源码学习】spring的AOP面向切面编程的实现解析

一:Advice(通知)(1)定义在连接点做什么,为切面增强提供织入接口.在spring aop中主要描述围绕方法调用而注入的切面行为.(2)spring定义了几个时刻织入增强行为的接口??=>org.springframework.aop.BeforeAdvice???org.springframework.aop.MethodBeforeAdvice??=>org.springframework.aop.AfterAdvice???org.springframework.aop.After

spring:AOP面向切面编程(注解)03

使用注解写aop时最好使用环绕通知写 切面类: /** * 用于记录日志的工具类,它里面提供了公共的代码 */ @Component("logger") @Aspect //表示当前类是一个切面类 public class Logger { @Pointcut("execution(* cn.flypig666.service.impl.*.*(..))") private void pt1(){}; /** * 前置通知 */ @Before("pt1(

Spring(三)AOP面向切面编程

原文链接:http://www.orlion.ga/205/ 一.AOP简介 1.AOP概念 参考文章:http://www.orlion.ml/57 2.AOP的产生 对于如下方法:     public class UserDAOImpl implements UserDAO{           public void saveUser(User user){      doSaveUser();      }     } 想在saveUser方法中执行保存用户之前和之后记录当前时间以求出