×

springaop spring aop pring

springaop(spring aop 可以实现什么)

admin admin 发表于2022-09-03 13:13:56 浏览112 评论0

抢沙发发表评论

本文目录

spring aop 可以实现什么


AOP技术利用一种称为“横切”的技术,解剖封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,这样就能减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。
实现原理  
前面在学习代理模式的时候,了解到代理模式分为动态代理和静态代理。现在我们就以代理模式为基础先实现我们自己的AOP框架,再来研究Spring的AOP的实现原理。
先以静态代理实现,静态代理关键是在代理对象和目标对象实现共同的接口,并且代理对象持有目标对象的引用。
公共接口代码:
1 public interface IHello {
2 /**
3 * 业务方法
4 * @param str
5 */
6 void sayHello(String str);
7 }
目标类代码:
1 public class Hello implements IHello{
2 @Override
3 public void sayHello(String str) {
4 System.out.println(“hello “+str);
5 }
6
7 }
代理类代码,我们给它添加日志记录功能,在方法开始前后执行特定的方法,是不是和AOP特别像呢?
public class ProxyHello implements IHello{
private IHello hello;
public ProxyHello(IHello hello) {
super();
this.hello = hello;
}
@Override
public void sayHello(String str) {
Logger.start();//添加特定的方法
hello.sayHello(str);
Logger.end();
}
}
日志类代码:
1 public class Logger {
2 public static void start(){
3 System.out.println(new Date()+ “ say hello start...“);
4 }
5
6 public static void end(){
7 System.out.println(new Date()+ “ say hello end“);
8 }
9 }
测试代码:
1 public class Test {
2 public static void main(String args) {
3 IHello hello = new ProxyHello(new Hello());//如果我们需要日志功能,则使用代理类
4 //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类
5 hello.sayHello(“明天“);
6 }
7 }
这样我们就实现了一个最简单的AOP,但是这样会存在一个问题:如果我们像Hello这样的类很多,那么,我们是不是要去写很多个HelloProxy这样的类呢。其实也是一种很麻烦的事。在jdk1.3以后,jdk跟我们提供了一个API java.lang.reflect.InvocationHandler的类, 这个类可以让我们在JVM调用某个类的方法时动态的为些方法做些什么事。下面我们就来实现动态代理的实现。
动态代理实现主要是实现InvocationHandler,并且将目标对象注入到代理对象中,利用反射机制来执行目标对象的方法。
接口实现与静态代理相同,代理类代码:
1 public class DynaProxyHello implements InvocationHandler{
2
3 private Object target;//目标对象
4 /**
5 * 通过反射来实例化目标对象
6 * @param object
7 * @return
8 */
9 public Object bind(Object object){
10 this.target = object;
11 return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
12 }
13
14 @Override
15 public Object invoke(Object proxy, Method method, Object args)
16 throws Throwable {
17 Object result = null;
18 Logger.start();//添加额外的方法
19 //通过反射机制来运行目标对象的方法
20 result = method.invoke(this.target, args);
21 Logger.end();
22 return result;
23 }
24
25 }
测试类代码:
1 public class DynaTest {
2 public static void main(String args) {
3 IHello hello = (IHello) new DynaProxyHello().bind(new Hello());//如果我们需要日志功能,则使用代理类
4 //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类
5 hello.sayHello(“明天“);
6 }
7 }
看完上面的代码可能和Spring AOP相比有一个问题,日志类只能在方法前后打印,但是AOP应该是可以在满足条件就可以执行,所有是否可以将DynaPoxyHello对象和日志操作对象(Logger)解耦呢?
看下面代码实现,将将DynaPoxyHello对象和日志操作对象(Logger)解耦:
我们要在被代理对象的方法前面或者后面去加上日志操作代码(或者是其它操作的代码),那么,我们可以抽象出一个接口,这个接口里就只有两个方法:一个是在被代理对象要执行方法之前执行的方法,我们取名为start,第二个方法就是在被代理对象执行方法之后执行的方法,我们取名为end。
Logger的接口:
1 public interface ILogger {
2 void start(Method method);
3 void end(Method method);
4 }
Logger的接口实现:
1 public class DLogger implements ILogger{
2 @Override
3 public void start(Method method) {
4 System.out.println(new Date()+ method.getName() + “ say hello start...“);
5 }
6 @Override
7 public void end(Method method) {
8 System.out.println(new Date()+ method.getName() + “ say hello end“);
9 }
10 }
动态代理类:
1 public class DynaProxyHello1 implements InvocationHandler{
2 //调用对象
3 private Object proxy;
4 //目标对象
5 private Object target;
6
7 public Object bind(Object target,Object proxy){
8 this.target=target;
9 this.proxy=proxy;
10 return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
11 }
12
13
14 @Override
15 public Object invoke(Object proxy, Method method, Object args)
16 throws Throwable {
17 Object result = null;
18 //反射得到操作者的实例
19 Class clazz = this.proxy.getClass();
20 //反射得到操作者的Start方法
21 Method start = clazz.getDeclaredMethod(“start“, new Class{Method.class});
22 //反射执行start方法
23 start.invoke(this.proxy, new Object{this.proxy.getClass()});
24 //执行要处理对象的原本方法
25 method.invoke(this.target, args);
26 //反射得到操作者的end方法
27 Method end = clazz.getDeclaredMethod(“end“, new Class{Method.class});
28 //反射执行end方法
29 end.invoke(this.proxy, new Object{method});
30 return result;
31 }
32
33 }
测试代码:
1 public class DynaTest1 {
2 public static void main(String args) {
3 IHello hello = (IHello) new DynaProxyHello1().bind(new Hello(),new DLogger());//如果我们需要日志功能,则使用代理类
4 //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类
5 hello.sayHello(“明天“);
6 }
7 }
通过上面例子,可以发现通过动态代理和发射技术,已经基本实现了AOP的功能,如果我们只需要在方法执行前打印日志,则可以不实现end()方法,这样就可以控制打印的时机了。如果我们想让指定的方法打印日志,我们只需要在invoke()方法中加一个对method名字的判断,method的名字可以写在xml文件中,这样我们就可以实现以配置文件进行解耦了,这样我们就实现了一个简单的spring aop框架。

spring的aop怎样实现


  • 实现原理  

  • 前面在学习代理模式的时候,了解到代理模式分为动态代理和静态代理。现在我们就以代理模式为基础先实现我们自己的AOP框架,再来研究Spring的AOP的实现原理。

    先以静态代理实现,静态代理关键是在代理对象和目标对象实现共同的接口,并且代理对象持有目标对象的引用。

    公共接口代码:

  • 1 public interface IHello {2     /**3      * 业务方法4      * @param str5      */6     void sayHello(String str);7 }

  • 目标类代码:

  • 1 public class Hello implements IHello{2     @Override3     public void sayHello(String str) {4         System.out.println(“hello “+str);5     }6     7 }

  • 代理类代码,我们给它添加日志记录功能,在方法开始前后执行特定的方法,是不是和AOP特别像呢?

  • public class ProxyHello implements IHello{    

  •    private IHello hello;    

  •    public ProxyHello(IHello hello) {        super();        this.hello = hello;

  •    }

  •    @Override    public void sayHello(String str) {

  •        Logger.start();//添加特定的方法        hello.sayHello(str);

  •        Logger.end();

  •    }

  • }

  • 日志类代码:

  • 1 public class Logger {2     public static void start(){3         System.out.println(new Date()+ “ say hello start...“);4     }5     6     public static void end(){7         System.out.println(new Date()+ “ say hello end“);8     }9 }

  • 测试代码:

  • 1 public class Test {2     public static void main(String args) {3         IHello hello = new ProxyHello(new Hello());//如果我们需要日志功能,则使用代理类4         //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类5         hello.sayHello(“明天“);    

  • 6     }7 }

  • 这样我们就实现了一个最简单的AOP,但是这样会存在一个问题:如果我们像Hello这样的类很多,那么,我们是不是要去写很多个HelloProxy这样的类呢。其实也是一种很麻烦的事。在jdk1.3以后,jdk跟我们提供了一个API java.lang.reflect.InvocationHandler的类, 这个类可以让我们在JVM调用某个类的方法时动态的为些方法做些什么事。下面我们就来实现动态代理的实现。-springaop

    动态代理实现主要是实现InvocationHandler,并且将目标对象注入到代理对象中,利用反射机制来执行目标对象的方法。

    接口实现与静态代理相同,代理类代码:

  • 1 public class DynaProxyHello implements InvocationHandler{ 2      3     private Object target;//目标对象 4     /** 5      * 通过反射来实例化目标对象 6      * @param object 7      * @return 8      */ 9     public Object bind(Object object){10         this.target = object;11         return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);12     }13     14     @Override15     public Object invoke(Object proxy, Method method, Object args)16             throws Throwable {17         Object result = null;18         Logger.start();//添加额外的方法19         //通过反射机制来运行目标对象的方法20         result = method.invoke(this.target, args);21         Logger.end();22         return result;23     }24     25 }

  • 测试类代码:

  • 1 public class DynaTest {2     public static void main(String args) {3         IHello hello = (IHello) new DynaProxyHello().bind(new Hello());//如果我们需要日志功能,则使用代理类4         //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类5         hello.sayHello(“明天“);6     }7 }

  • 看完上面的代码可能和Spring AOP相比有一个问题,日志类只能在方法前后打印,但是AOP应该是可以在满足条件就可以执行,所有是否可以将DynaPoxyHello对象和日志操作对象(Logger)解耦呢?-pring

    看下面代码实现,将将DynaPoxyHello对象和日志操作对象(Logger)解耦:

    我们要在被代理对象的方法前面或者后面去加上日志操作代码(或者是其它操作的代码),那么,我们可以抽象出一个接口,这个接口里就只有两个方法:一个是在被代理对象要执行方法之前执行的方法,我们取名为start,第二个方法就是在被代理对象执行方法之后执行的方法,我们取名为end。-springaop

    Logger的接口:

  • 1 public interface ILogger {2     void start(Method method);3     void end(Method method);4 }

  • Logger的接口实现:

  • 1 public class DLogger implements ILogger{ 2     @Override 3     public void start(Method method) { 4         System.out.println(new Date()+ method.getName() + “ say hello start...“); 5     } 6     @Override 7     public void end(Method method) { 8         System.out.println(new Date()+ method.getName() + “ say hello end“); 9     }10 }

  • 动态代理类:

  • 1 public class DynaProxyHello1 implements InvocationHandler{ 2     //调用对象 3     private Object proxy; 4     //目标对象 5     private Object target; 6      7     public Object bind(Object target,Object proxy){ 8         this.target=target; 9         this.proxy=proxy;10         return Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);11     }12     13     14     @Override15     public Object invoke(Object proxy, Method method, Object args)16             throws Throwable {17         Object result = null;18         //反射得到操作者的实例19         Class clazz = this.proxy.getClass();20         //反射得到操作者的Start方法21         Method start = clazz.getDeclaredMethod(“start“, new Class{Method.class});22         //反射执行start方法23         start.invoke(this.proxy, new Object{this.proxy.getClass()});24         //执行要处理对象的原本方法25         method.invoke(this.target, args);26         //反射得到操作者的end方法27         Method end = clazz.getDeclaredMethod(“end“, new Class{Method.class});28         //反射执行end方法29         end.invoke(this.proxy, new Object{method});30         return result;31     }32     33 }

  • 测试代码:

  • 1 public class DynaTest1 {2     public static void main(String args) {3         IHello hello = (IHello) new DynaProxyHello1().bind(new Hello(),new DLogger());//如果我们需要日志功能,则使用代理类4         //IHello hello = new Hello();//如果我们不需要日志功能则使用目标类5         hello.sayHello(“明天“);6     }7 }

  • 通过上面例子,可以发现通过动态代理和发射技术,已经基本实现了AOP的功能,如果我们只需要在方法执行前打印日志,则可以不实现end()方法,这样就可以控制打印的时机了。如果我们想让指定的方法打印日志,我们只需要在invoke()方法中加一个对method名字的判断,method的名字可以写在xml文件中,这样我们就可以实现以配置文件进行解耦了,这样我们就实现了一个简单的spring aop框架。-pring


Spring AOP 一般用在什么场景中


AOP,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子。

在不改变原有的逻辑的基础上,增加一些额外的功能。代理也是这个功能,读写分离也能用aop来做。

扩展资料:

AOP/OOP区分

AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。

而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。

参考资料来源:百度百科-AOP (面向切面编程)


spring AOP的原理,以及什么是AOP


Spring
AOP是编程框架
AOP是OOP的延续,是Aspect
Oriented
Programming的缩写,意思是面向方面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。
-springaop

Spring的AOP有什么作用


AOP:面向切面,是一种编程思想,OOP的延续。将系统中非核心的业务提取出来,进行单独处理。比如事务、日志和安全等。这个简单来说就是可以在一段程序之前或者之后做一些事。

spring配置aop的方式有哪些


1. 基于xml配置文件的代理配置方式
这种方式在2.0以后很少用了,原因是配置项过多,过于繁琐。但对于理解Spring AOP还是很有帮助的
1.1 定义通知
《bean id=“advice“ class=“yourAdviceImpl“ /》
1.2 定义切点
要定义一个切点,可以选择使用正则表达式方式声明的切点或者AspectJ方式声明的切点。对正则表达式切点,使用Perl5RegexpMethodPointcut或JdkRegexpMethodPointcut(Java
1.4以上版本,不需要Jakarta ORO的支持了);对AspectJ切点,使用AspectJExpressPointcut
《bean id=“pointcut“ class=“org.springframework.aop.support.JdkRegexpMethodPointcut“》
《property name=“pattern“ value=“yourRegularExpression“ /》
《/bean》
《bean id=“pointcut“ class=“org.springframework.aop.aspectj.AspectJExpressionPointcut“》
《property name=“expression“ value=“yourAspectJExpression“ /》
《/bean》
1.3 定义通知者
DefaultPointcutAdvisor是Spring提供的默认通知者,它需要提供通知和切点的引用。
Spring也提供了RegexpMethodPointcutAdvisor和AspectJExpressionPointcutAdvisor来对应两种声明切点的方式,不用再单独定义切点。
《bean id=“advisor“ class=“org.springframework.aop.support.DefaultPointcutAdvisor“》
《property name=“advice“ ref=“advice“ /》
《property name=“pointcut“ ref=“pointcut“ /》
《/bean》
《bean id=“advisor“ class=“org.springframework.aop.support.RegexpMethodPointcutAdvisor“》
《property name=“advice“ ref=“advice“ /》
《property name=“pattern“ value=“yourRegularExpression“ /》
《/bean》
《bean id=“advisor“ class=“org.springframework.aop.aspectj.AspectJExpressionPointcut“》
《property name=“advice“ ref=“advice“ /》
《property name=“expression“ value=“yourAspectjExpression“ /》
《/bean》
1.4 定义ProxyFactoryBean
《bean id=“yourBean“ class=“org.springframework.aop.framework.ProxyFactoryBean》
《property name=“target“ ref=“yourTargetBean“ /》
《property name=“interceptorNames“ value=“advisor“ /》
《property name=“proxyInterfaces“ value=“interfaceClass“ /》
《/bean》
interceptorNames和proxyInterfaces都是数组属性,所以可以声明要使用的一个list,也可以让Spring自动把单个值转化为数组
上面明确定义了要对那个targetBean应用代理生成切面实例。如果不想限制targetBean,可以让Spring为所有匹配切点声明的bean生成切面实例,这样就不用一个个定义ProxyFactoryBean了,只需要定义
《bean class=“org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator“ /》
这是一个BeanPostProcessor,所以Spring会自动识别并在bean的声明周期使用
2 利用2.0以后使用aop标签
《aop:config》
《aop:aspect ref=““》
《aop:pointcut id=“performance“ expression=“execution(* *.perform(..))“ /》
《aop:before method=““ pointcut-ref=“performance“ /》
《aop:before method=““ pointcut=“execution(* *.perform(..))“ /》
《aop:after-returning method=““ pointcut=“execution(* *.perform(..))“ /》
《aop:after-throwing method=““ pointcut=“execution(* *.perform(..))“ /》
《/aop:aspect》
《/aop:config》
3 利用Annotation
3.1 利用@Aspect将一个POJO类声明为一个切面。
3.2 定义切点
@Pointcut(“execution(* *.perform(..))“)
public void performance(){}
通过@Pointcut定义的切点的名字就是它所注解的方法的名字,因此例子中的切点名字是
performance()。这里声明的performance()方法实际圣只是一个标记,为@Pointcut提供附加的点,并不要求有实际意义。
3.3 定义通知
对要执行切面的方法,通过@Before(“performance()“),@AfterReturning
(“performance()“)来定义通知。注意这里提供的切点名称,是performance(),而不是performance
如果对上面的两点不是很理解,也可以省略@Pointcut,而将AspectJ表达式直接定义在@Before等通知中,将上面的两步合为一步,如@Before(“execution(* *.perform(..))“)
3.4 通知Spring创建代理
《aop:aspectj-autoproxy》
这实际上相当于声明了一个AnnotationAwareAspectJAutoProxyCreator,从而根据@Pointcut声明的切点来自动代理匹配的bean实例
4 在Spring中结合进AspectJ
对于超出Spring AOP支持范围的,可以采用这种方式。只需要在Spring中配置AspectJ的Class实例时让Spring能够获得AspectJ类的实例就可以了,比如
《bean class=“a_aspectj_class“ factory-method=“aspectOf“》
《preperty .... /》
《/bean》
-pring

spring的aop是什么意思


在AOP中有几个概念:—方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。—连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。—通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。—切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。所以“”实际上是定义横切逻辑,就是在连接点上做什么,“”则定义了在哪些连接点应用什么。Spring这样做的好处就是可以让多个横切逻辑(即定义的)多次使用,提供可重用性。你后面的两个类实际上就是实现横切逻辑的不同方式,一种需要实现特定接口,一种以POJO+Annotation,在功能上没有太大差别,只是方式不同。
-springaop

spring aop 有什么用途


给你举一个例子,比如一个注册登录系统,当然需要注册的地方有很多,你可能要做一个防止用户名重复注册的模块,这个时候就可以用到Spring的aop了!
在你开发大型的应用时,aop可以发挥很大的功能,对于你模块的耦合,以后的管理,功能升级……!都有很大的帮助
好好的理解一下,争取自己去写一个aop出来!
-pring

如何理解Spring的AOP


Spring的AOP面向切面编程,就是横向的,比如程序运行时都要建日志,相当于SQL的触发器。

Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架。-springaop

Spring特点:

1、方便解耦,简化开发

通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。-pring

2、AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。

3、声明式事务的支持

在Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

4、方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:Spring对Junit4支持,可以通过注解方便的测试Spring程序。

5、方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如Struts,Hibernate、Hessian、Quartz)等的直接支持。

6、降低Java EE API的使用难度

Spring对很多难用的Java EE API(如JDBC,JavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

7、Java 源码是经典学习范例

Spring的源码设计精妙、结构清晰、匠心独运,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。-springaop


有人能通俗介绍下SPRING的AOP吗


想简单通俗的说,额,有难度.AOP主要是针对事物处理来说吧,而且是相对于以前的编程式事物处理的,不用AOP的话,我们得通过硬编码的方式将事物处理写在方法中,有了AOP之后,我们只需要在spring的配置文件中配置一下事物就可以了,这就叫声明式事物处理.一般配置时是通过配置匹配某个格式的方法名,当运行到这种方法的时候spring就会拦截下它来,并给它加上事物的处理了
-pring