Spring之AOP
spring作用
spring作用Spring是一个开源的企业级Java应用程序开发框架,它提供了一套全面的基础架构,以帮助开发者更容易地构建可伸缩的Web应用程序。
Spring的主要作用如下:1. IoC(控制反转)容器:Spring的核心是IoC容器,它负责对象的创建、销毁和管理。
传统的开发方式中,对象的创建和销毁都是由开发者手动管理的,而通过使用Spring的IoC容器,对象的声明周期完全交由Spring管理,开发者只需要定义对象的配置信息,Spring会根据配置信息自动创建对象,并在不需要时进行销毁,大大减少了开发工作量。
2. AOP(面向切面编程):Spring通过AOP模块提供了对切面编程的支持,可以将横切关注点(如日志记录、事务管理等)从核心业务逻辑中分离出来,提高代码的可维护性和重用性。
通过使用Spring的AOP功能,开发者可以自定义切点,将横切逻辑织入到核心逻辑中。
3. 数据访问抽象:Spring提供了对各种数据访问技术的抽象,包括JDBC、ORM框架(如Hibernate、MyBatis)和NoSQL数据库。
通过Spring的数据访问抽象,开发者可以通过配置简单地切换不同的数据访问技术,不需要修改业务逻辑代码,提高了代码的灵活性和可扩展性。
4. Web应用开发:Spring提供了一套完整的Web应用开发框架,包括MVC框架、RESTful Web Service支持和Web容器集成。
通过Spring MVC框架,开发者可以快速开发出高性能、易扩展的Web应用程序,通过RESTful Web Service支持,开发者可以基于HTTP协议构建出面向资源的Web服务,并进行跨平台的数据交互。
5. 安全性:Spring提供了一套完善的安全性框架,包括身份验证、授权和数据加密等功能。
开发者可以通过配置简单地集成安全性功能到应用程序中,保护数据的安全性和完整性。
6. 事务管理:Spring提供了对事务管理的支持,可以轻松地管理分布式事务,确保数据的一致性。
SpringAOP的原理和应用场景
SpringAOP的原理和应用场景SpringAOP(Aspect-Oriented Programming)是Spring框架中的一个重要组成部分,它提供了一种通过预定义的方式,将横切关注点(Cross-cutting Concerns)与业务逻辑进行解耦的机制。
本文将介绍SpringAOP的原理及其在实际应用场景中的应用。
一、SpringAOP的原理SpringAOP基于代理模式(Proxy Pattern)实现。
在SpringAOP中,通过生成与原始类(被代理类)具有相同接口的代理类,将横切逻辑编织到业务逻辑中。
在运行时,当调用代理类的方法时,会在方法执行前、后或异常抛出时插入相应的横切逻辑代码。
具体而言,SpringAOP使用了以下几个核心概念:1. 切面(Aspect):切面是横切逻辑的模块化单元,它包含了一组通知(Advice)和切点(Pointcut)。
2. 通知(Advice):通知定义了实际的横切逻辑代码,并规定了何时执行该代码。
SpringAOP提供了五种类型的通知:前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)。
3. 切点(Pointcut):切点指定了在哪些连接点(Join Point)上执行通知。
连接点可以是方法调用、属性访问等程序执行的点。
4. 连接点(Join Point):连接点是程序执行过程中的一个特定点,如方法调用前、方法调用后等。
通知通过切点来选择连接点。
5. 织入(Weaving):织入是将切面应用到目标对象,并创建代理对象的过程。
织入可以在编译时、类加载时或运行时进行。
二、SpringAOP的应用场景SpringAOP可应用于各种场景,用于解决跨越多个模块或类的横切关注点问题。
以下是一些常见的SpringAOP应用场景:1. 日志记录:通过在关键方法的前后插入日志代码,实现对系统运行状态的监控和记录。
SpringAOP示例与实现原理总结——传统springaop、基于切面注入、基于@Asp。。。
SpringAOP⽰例与实现原理总结——传统springaop、基于切⾯注⼊、基于@Asp。
⼀、代码实践1)经典的Spring Aop经典的spring aop,是基于动态代理技术的。
实现⽅式上,最常⽤的是实现MethodInterceptor接⼝来提供环绕通知,创建若⼲代理,然后使⽤ProxyBeanFactory配置⼯⼚bean,⽣成拦截器链,完成拦截。
⽰例如下:1package demo.spring;23import org.aopalliance.intercept.MethodInterceptor;4import org.aopalliance.intercept.MethodInvocation;5import org.junit.Test;6import org.junit.runner.RunWith;7import org.springframework.beans.factory.annotation.Autowired;8import org.springframework.test.context.ContextConfiguration;9import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;1011 @RunWith(SpringJUnit4ClassRunner.class)12 @ContextConfiguration("classpath:spring-config.xml")13public class TraditionalSpringAopDemo {14 @Autowired15private Service proxy;1617 @Test18public void test() {19 proxy.execute("hello world!");20 }21 }2223interface Service {24void execute(String str);25 }2627class ServiceImpl implements Service {28 @Override29public void execute(String str) {30 System.out.println("execute invoke: " + str);31 }32 }3334class Interceptor1 implements MethodInterceptor {35 @Override36public Object invoke(MethodInvocation methodInvocation) throws Throwable {37 System.out.println("interceptor1,before invoke");38 Object ret = methodInvocation.proceed();39 System.out.println("interceptor1,after invoke");40return ret;41 }42 }4344class Interceptor2 implements MethodInterceptor {45 @Override46public Object invoke(MethodInvocation methodInvocation) throws Throwable {47 System.out.println("interceptor2,before invoke");48 Object ret = methodInvocation.proceed();49 System.out.println("interceptor2,after invoke");50return ret;51 }52 }xml⽂件配置:1<?xml version="1.0" encoding="UTF-8"?>2<beans xmlns="/schema/beans"3 xmlns:xsi="/2001/XMLSchema-instance"4 xmlns:context="/schema/context"5 xmlns:aop="/schema/aop"6 xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /schema/context /schema/context/sprin 78<context:component-scan base-package="demo.spring"/>910<bean class="demo.spring.ServiceImpl" id="service"></bean>11<bean class="demo.spring.Interceptor1" id="interceptor1"></bean>12<bean class="demo.spring.Interceptor2" id="interceptor2"></bean>13<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="proxy">14<property name="target" ref="service"/>15<property name="interceptorNames">16<list>17<value>interceptor1</value>18<value>interceptor2</value>19</list>20</property>21</bean>22</beans>结果:interceptor1,before invokeinterceptor2,before invokeexecute invoke: hello world!interceptor2,after invokeinterceptor1,after invoke可以看到拦截链的执⾏过程与拦截器顺序的关系。
java面试题 aop原理
java面试题 aop原理一、概述面向切面编程(AOP)是一种编程范式,它允许在运行时通过拦截方法调用来修改方法的行为。
在Java中,Spring框架提供了强大的AOP支持,使得我们能够在不修改原有代码的情况下,对方法调用进行拦截、增强和通知。
二、AOP的基本概念1. 面向切面编程(Aspect):一个切面描述了一组与多个方法相关的行为,这些行为在方法执行前后发生。
2. 连接点(Join Point):在程序执行过程中,方法被调用的地方。
3. 切点(Pointcut):定义了需要拦截的方法或类的模式。
4. 通知(Advice):在方法调用前后执行的行为,如日志记录、性能统计、异常处理等。
5. 切面(Aspect):包含了多个通知和对应的切点。
6. 代理(Proxy):在切面被应用后,目标对象将被代理对象替换,所有的方法调用都将通过代理对象进行。
三、Spring AOP的实现原理Spring AOP的实现基于动态代理和CGLIB库,通过在运行时创建目标对象的代理对象,拦截方法调用,并在方法执行前后插入通知。
具体实现过程如下:1. 定义切点、通知和目标对象,形成一个切面。
2. 创建一个 Advised Object,将切面、切点和目标对象添加进去。
3. 使用 Spring AOP 配置类,将 Advised Object 与代理工厂关联起来。
4. 当方法被调用时,代理对象将拦截方法调用,并根据切点匹配规则确定是否需要执行通知。
5. 执行通知后,继续执行原始方法。
四、Spring AOP的优点和缺点优点:1. 不需要修改原有代码,即可实现横切功能的修改。
2. 可以灵活地定义通知行为,包括日志、性能统计、事务管理、安全控制等。
3. 可以在运行时动态地调整系统行为。
缺点:1. 性能开销:Spring AOP 在创建代理对象时,会增加一定的性能开销。
特别是在处理大量方法调用时,性能问题可能会变得明显。
2. 依赖 Spring 框架:Spring AOP 是 Spring 框架的一部分,因此使用 Spring AOP 的系统需要依赖 Spring 框架的其他组件。
面试之Spring框架IOC和AOP的实现原理
⾯试之Spring框架IOC和AOP的实现原理本⽂讲的是⾯试之Spring框架IOC和AOP的实现原理, IoC(Inversion of Control) (1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,⽽不是传统实现中,由程序代码直接操控。
控制权由应⽤代码中转到了外部容器,控制权的转移是所。
IoC(Inversion of Control)(1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,⽽不是传统实现中,由程序代码直接操控。
控制权由应⽤代码中转到了外部容器,控制权的转移是所谓反转。
对于Spring⽽⾔,就是由Spring来控制对象的⽣命周期和对象之间的关系;IoC还有另外⼀个名字——“依赖注⼊(Dependency Injection)”。
从名字上理解,所谓依赖注⼊,即组件之间的依赖关系由容器在运⾏期决定,即由容器动态地将某种依赖关系注⼊到组件之中。
(2). 在Spring的⼯作⽅式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运⾏到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。
所有的类的创建、销毁都由 spring来控制,也就是说控制对象⽣存周期的不再是引⽤它的对象,⽽是spring。
对于某个具体的对象⽽⾔,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
(3). 在系统运⾏中,动态的向某个对象提供它所需要的其他对象。
(4). 依赖注⼊的思想是通过反射机制实现的,在实例化⼀个类时,它通过反射调⽤类中set⽅法将事先保存在HashMap中的类属性注⼊到类中。
总⽽⾔之,在传统的对象创建⽅式中,通常由调⽤者来创建被调⽤者的实例,⽽在Spring中创建被调⽤者的⼯作由Spring来完成,然后注⼊调⽤者,即所谓的依赖注⼊or控制反转。
Spring中IOC和AOP的深入讲解
Spring中IOC和AOP的深⼊讲解前⾔Spring是⼀个开源框架,Spring是于2003 年兴起的⼀个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍⽣⽽来。
它是为了解决企业应⽤开发的复杂性⽽创建的。
Spring使⽤基本的JavaBean来完成以前只可能由EJB完成的事情。
然⽽,Spring的⽤途不仅限于服务器端的开发。
从简单性、可测试性和松耦合的⾓度⽽⾔,任何Java应⽤都可以从Spring中受益。
简单来说,Spring是⼀个轻量级的控制反转(IoC)和⾯向切⾯(AOP)的容器框架。
这篇⽂章主要讲 Spring 中的⼏个点,Spring 中的 IOC,AOP,下⼀篇说说 Spring 中的事务操作,注解和 XML 配置。
Spring 简介Spring 是⼀个开源的轻量级的企业级框架,其核⼼是反转控制 (IoC) 和⾯向切⾯ (AOP) 的容器框架。
我们可以把 Spring 看成是对象的容器,容器中可以包含很多对象,所以 Spring 有很多强⼤的功能。
⼀句话,Spring 是项⽬中对象的管家,负责管理项⽬中⽤到的所有对象。
所以在项⽬三层架构中,Spring 不属于某⼀特定层。
Spring 的 Hello World想要构建⼀个 Spring 的⼊门程序,我们需要导⼊ 4 个核⼼包和 2 个辅助包,创建⼀个实体类,最主要的是编写核⼼配置⽂件,applicationContext.xml 放在 src 下。
最后写⼀个测试类即可。
此时在测试类中我们不需要在使⽤ new 关键字去创建对象了。
这也正是 Spring 的作⽤所在,会⾃动给我创建对象。
上图展⽰的就是最基本的演⽰,也是很容易就理解了,配置⽂件中配置了 user 对象,我们通过加载配置⽂件来获取对象从⽽避免了使⽤ new 来创建。
springAop后置通知AfterReturningAdvice实现原理和代码案例
springAop后置通知AfterReturningAdvice实现原理和代码案例Spring AOP(Aspect-Oriented Programming)是一种面向切面编程的方式,通过在代码中定义切面、通知、切点等元素,可以实现对方法的增强,例如在方法执行之前、之后、抛出异常时等插入特定的代码逻辑。
其中,后置通知(After Returning Advice)是一种在被通知方法成功执行后执行的通知。
后置通知的实现原理是利用动态代理机制,通过代理对象来调用目标对象方法,从而实现对方法的增强。
Spring AOP提供了两种方式来实现后置通知:一种是使用基于配置的方式,另一种是使用基于注解的方式。
下面以基于注解的方式为例,介绍后置通知的实现原理和代码案例。
实现后置通知的步骤如下:1. 创建一个普通的Java类,作为目标对象,其中包含一个被通知的方法。
```javapublic class UserServicepublic void addUser(String username)System.out.println("Add user: " + username);}``````javapublic class LogAspectpublic void afterReturning(JoinPoint joinPoint, Object result)System.out.println("Method executed successfully: " + joinPoint.getSignature(.getName();}``````javapublic class AppConfigpublic UserService userServicreturn new UserService(;}public LogAspect logAspecreturn new LogAspect(;}``````javapublic class UserServiceTestprivate UserService userService;public void testAddUseuserService.addUser("testUser");}```5.运行测试类,控制台输出:```Add user: testUserMethod executed successfully: addUser```代码解析:- returning:定义一个Object类型的参数result,用于接收目标方法的返回值。
Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
Spring技术内幕——深入解析Spring架构与设计原理(二)AOPAOP联盟定义的AOP体系结构把与AOP相关的概念大致分为了由高到低、从用法到实现的三个层次。
关于这个体系结构,个人的理解是这样的,从上往下,最高层是语言和开发环境,在这个环境中可以看到几个重要的概念:base可以视为待增加对象,或者说目标对象;aspect指切面,通常包含对于base的增加应用;configuration可以看成是一种编织或者说配置,通过在AOP体系中提供这个configuration配置环境,可以把base和aspect结合起来,从而完成切面向目标对象的编织实现。
对Spring平台或者说生态系统来说,AOP是Spring框架的核心功能模块之一。
AOP与IOC容器的结合用法, 为应用开发或者Spring自身功能的扩展都提供了许多方便。
Spring AOP的实现和其他特性的实现一样,十分丰盛,除了可以用法Spring本身提供的AOP实现之外,还封装了业界优秀的AOP解决计划AspectJ来让应用用法。
在这里,主要对Spring自身的AOP实现原理做一些解析;在这个AOP实现中,Spring 充分利用了IOC容器Proxy代理对象以及AOP拦截器的功能特性,通过这些对AOP基本功能的封装机制,为用户提供了AOP的实现框架。
所以,要了解这些AOP的基本实现,需要我们对Java 的Proxy机制有一些基本了解。
AOP实现的基本线索 AOP实现中,可以看到三个主要的步骤,一个是代理对象的生成,然后是拦截器的作用,然后是Aspect编织的实现。
AOP框架的丰盛,很大程度体现在这三个详细实现中,所具有的丰盛的技术挑选,以及如何实现与IOC容器的无缝结合。
究竟这也是一个十分核心的模块,需要满足不同的应用需求带来的解决计划需求。
在Spring AOP的实现原理中,我们主要举ProxyFactoryBean的实现作为例子和实现的基本线索举行分析;很大一个缘由,是由于ProxyFactoryBean是在Spring IoC环境中,创建AOP应用的最底层办法,从中,可以看到一条实现AOP的基本线索。
Java框架------Spring框架AOP注解(@Aspect和@Around)
Java框架------Spring框架AOP注解(@Aspect和@Around)AOP 中的声明主要有两种基于XML和基于Annotation之前的为借助xml ,现在介绍⼀下借助注解的⽅式,修改之前的⼩项⽬常见五种通知类型org.springframework.aop.MethodBeforeAdvice(前置通知)在⽅法之前⾃动执⾏的通知称为前置通知,可以应⽤于权限管理等功能。
org.springframework.aop.AfterReturningAdvice(后置通知)在⽅法之后⾃动执⾏的通知称为后置通知,可以应⽤于关闭流、上传⽂件、删除临时⽂件等功能。
org.aopalliance.intercept.MethodInterceptor(环绕通知)在⽅法前后⾃动执⾏的通知称为环绕通知,可以应⽤于⽇志、事务管理等功能。
org.springframework.aop.ThrowsAdvice(异常通知)在⽅法抛出异常时⾃动执⾏的通知称为异常通知,可以应⽤于处理异常记录⽇志等功能。
org.springframework.aop.IntroductionInterceptor(引介通知)在⽬标类中添加⼀些新的⽅法和属性,可以应⽤于修改旧版本程序(增强类)。
常见注解@Aspect:作⽤是把当前类标识为⼀个切⾯供容器读取@Around:环绕增强,相当于MethodInterceptor@AfterReturning:后置增强,相当于AfterReturningAdvice,⽅法正常退出时执⾏@Pointcut:Pointcut是植⼊Advice的触发条件。
每个Pointcut的定义包括2部分,⼀是表达式,⼆是⽅法签名。
⽅法签名必须是 public及void型。
可以将Pointcut中的⽅法看作是⼀个被Advice引⽤的助记符,因为表达式不直观,因此我们可以通过⽅法@Before:标识⼀个前置增强⽅法,相当于BeforeAdvice的功能,相似功能的还有@AfterThrowing:异常抛出增强,相当于ThrowsAdvice@After: final增强,不管是抛出异常或者正常退出都会执⾏使⽤pointcut代码@DeclareParents ⽤于定义引介通知,相当于IntroductionInterceptor(不要求掌握)。
举例说明事务注解失效的场景
举例说明事务注解失效的场景事务注解是在Spring框架中非常常用的一种方式,用于管理数据库事务。
但是在某些场景下,事务注解可能会失效,导致事务无法正常管理。
本文将举例说明事务注解失效的场景。
一、Spring AOP代理问题Spring AOP代理是实现事务注解的重要手段之一。
但是,在某些情况下,AOP代理可能会失效,导致事务无法正常管理。
1.1 代理对象为类而不是接口当我们使用基于类的AOP代理时,如果被代理的对象没有实现任何接口,则Spring将会使用CGLIB创建一个子类来实现AOP。
这个子类并不会继承父类上的@Transactional注解,因此在使用该子类时,事务注解将会失效。
1.2 代理对象不是由Spring容器创建如果我们手动创建了一个对象,并且使用了@Transactional注解来管理它的事务,则该注解将不起作用。
因为Spring只能对由容器创建的Bean进行AOP代理。
二、多线程问题当我们在多线程环境下使用事务注解时,可能会遇到以下问题:2.1 一个线程中开启了一个新的事务,并在该线程中进行了操作;另一个线程中也开启了一个新的事务,并尝试对第一个线程所操作过的数据进行操作。
此时,第二个线程将无法获取到第一个线程所开启的事务,从而导致事务注解失效。
2.2 在多线程环境下,如果我们使用ThreadLocal来管理事务,则可能会遇到线程池重用问题。
当一个线程执行完毕后,我们需要手动清除ThreadLocal中的内容,否则当该线程被再次使用时,它仍然会持有之前的ThreadLocal内容,从而导致事务注解失效。
三、异常处理问题在使用@Transactional注解时,我们需要注意异常处理问题。
如果我们在方法中捕获了异常,并且没有将其向上抛出,则该异常将不会被Spring捕获到,并且事务将不会回滚。
四、数据库引擎问题在某些数据库引擎中,例如MyISAM,在执行DML操作时并不支持事务。
因此,在使用这些数据库引擎时,即使我们使用了@Transactional注解来管理事务,也无法实现回滚操作。
Spring框架——AOP(面向切面编程)详解
Spring框架——AOP(⾯向切⾯编程)详解1 AOP概述●AOP(Aspect-Oriented Programming,⾯向切⾯编程):是⼀种新的⽅法论,是对传统 OOP(Object-Oriented Programming,⾯向对象编程)的补充。
●AOP编程操作的主要对象是切⾯(aspect),⽽切⾯模块化横切关注点。
●在应⽤AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能应⽤在哪⾥,以什么⽅式应⽤,并且不必修改受影响的类。
这样⼀来横切关注点就被模块化到特殊的类⾥——这样的类我们通常称之为“切⾯”。
●AOP的好处:○每个事物逻辑位于⼀个位置,代码不分散,便于维护和升级○业务模块更简洁,只包含核⼼业务代码2 AOP术语2.1 横切关注点 从每个⽅法中抽取出来的同⼀类⾮核⼼业务。
(抽离到⽅法中处理⾮核⼼业务)2.2 切⾯(Aspect) 封装横切关注点信息的类,每个关注点体现为⼀个通知⽅法。
2.3 通知(Advice) 切⾯必须要完成的各个具体⼯作2.4 ⽬标(Target) 被通知的对象2.5 代理(Proxy) 向⽬标对象应⽤通知之后创建的代理对象2.6 连接点(Joinpoint) 横切关注点在程序代码中的具体体现,对应程序执⾏的某个特定位置。
例如:类某个⽅法调⽤前、调⽤后、⽅法捕获到异常后等。
在应⽤程序中可以使⽤横纵两个坐标来定位⼀个具体的连接点:2.7 切⼊点(pointcut): 定位连接点的⽅式。
每个类的⽅法中都包含多个连接点,所以连接点是类中客观存在的事物。
如果把连接点看作数据库中的记录,那么切⼊点就是查询条件——AOP可以通过切⼊点定位到特定的连接点。
切点通过org.springframework.aop.Pointcut 接⼝进⾏描述,它使⽤类和⽅法作为连接点的查询条件。
3 AspectJ3.1 简介AspectJ:Java社区⾥最完整最流⾏的AOP框架。
spring-aop详解
Spring AOPSpring 是由多个部分组成,包括AOP、DAO、Conetxt、Web、MVC,并且他们都已IoC 容器为基础。
Spring 这么多功能都是由于其IoC 容器的特性,实现了对多种框架的集成,但 AOP 是个例外,它不是对某个框架的集成,而是提供了面向方面编程的功能,你可以自由选择是否使用AOP。
AOP 提供了强大的中间件解决方案,这使得IoC 容器更加完善。
我们可以把AOP 看做是 Sping 的一种增强,它使得 Spring 可以不需要 EJB 就能够提供声明式事务管理,或者也可以使用Spring AOP 框架的全部功能来实现自己定义的切面。
AOP将应用系统分为两部分,核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的方面Crosscutting enterprise concerns,例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。
Spring AOP的核心设计思想:代理模式AOP常用专业术语:①方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。
事务管理是J2EE应用中一个很好的横切关注点例子。
方面用Spring的Advisor或拦截器实现。
②连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
③通知(Advice):在特定的连接点,AOP框架执行的动作。
各种类型的通知包括“around”、“before”和“throws”通知。
通知类型将在下面讨论。
许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。
④切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。
SpringAop实例@Aspect、@Before、@AfterReturning@Ar。。。
SpringAop实例@Aspect、@Before、@AfterReturning@Ar。
⽤过spring框架进⾏开发的⼈,多多少少会使⽤过它的AOP功能,都知道有@Before、@Around和@After等advice。
最近,为了实现项⽬中的输出⽇志和权限控制这两个需求,我也使⽤到了AOP功能。
我使⽤到了@Before、@Around这两个advice。
但在,使⽤过程中,却对它们的执⾏顺序并不清楚。
为了弄清楚在不同情况下,这些advice到底是以怎么样的⼀个顺序进⾏执⾏的,我作了个测试,在此将其记录下来,以供以后查看。
前提对于AOP相关类(aspect、pointcut等)的概念,本⽂不作说明。
对于如何让spring框架扫描到AOP,本⽂也不作说明。
情况⼀: ⼀个⽅法只被⼀个Aspect类拦截当⼀个⽅法只被⼀个Aspect拦截时,这个Aspect中的不同advice是按照怎样的顺序进⾏执⾏的呢?请看:添加 PointCut类该pointcut⽤来拦截test包下的所有类中的所有⽅法。
package test;import ng.annotation.Pointcut;public class PointCuts {@Pointcut(value = "within(test.*)")public void aopDemo() {}}package test; import ng.annotation.Pointcut; public class PointCuts { @Pointcut(value= "within(test.*)") public void aopDemo() { } }添加Aspect类该类中的advice将会⽤到上⾯的pointcut,使⽤⽅法请看各个advice的value属性。
package test;import ng.JoinPoint;import ng.ProceedingJoinPoint;import ng.annotation.*;import ponent;@Component@Aspectpublic class Aspect1 {@Before(value = "test.PointCuts.aopDemo()")public void before(JoinPoint joinPoint) {System.out.println("[Aspect1] before advise");}@Around(value = "test.PointCuts.aopDemo()")public void around(ProceedingJoinPoint pjp) throws Throwable{System.out.println("[Aspect1] around advise 1");pjp.proceed();System.out.println("[Aspect1] around advise2");}@AfterReturning(value = "test.PointCuts.aopDemo()")public void afterReturning(JoinPoint joinPoint) {System.out.println("[Aspect1] afterReturning advise");}@AfterThrowing(value = "test.PointCuts.aopDemo()")public void afterThrowing(JoinPoint joinPoint) {System.out.println("[Aspect1] afterThrowing advise");}@After(value = "test.PointCuts.aopDemo()")public void after(JoinPoint joinPoint) {System.out.println("[Aspect1] after advise");}}添加测试⽤Controller添加⼀个⽤于测试的controller,这个controller中只有⼀个⽅法,但是它会根据参数值的不同,会作出不同的处理:⼀种是正常返回⼀个对象,⼀种是抛出异常(因为我们要测试@AfterThrowing这个advice)package test;import test.exception.TestException;import org.springframework.http.HttpStatus;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping(value = "/aop")public class AopTestController {@ResponseStatus(HttpStatus.OK)@RequestMapping(value = "/test", method = RequestMethod.GET)public Result test(@RequestParam boolean throwException) {// case 1if (throwException) {System.out.println("throw an exception");throw new TestException("mock a server exception");}// case 2System.out.println("test OK");return new Result() {{this.setId(111);this.setName("mock a Result");}};}public static class Result {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}}}测试正常情况在浏览器直接输⼊以下的URL,回车:http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=false我们会看到输出的结果是:[Aspect1] around advise 1[Aspect1] before advisetest OK[Aspect1] around advise2[Aspect1] after advise[Aspect1] afterReturning advise测试异常情况在浏览器中直接输⼊以下的URL,回车:http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=true我们会看到输出的结果是:1.[Aspect1] around advise 12.[Aspect1] before advise3.throw an exception4.[Aspect1] after advise5.[Aspect1] afterThrowing advise结论在⼀个⽅法只被⼀个aspect类拦截时,aspect类内部的 advice 将按照以下的顺序进⾏执⾏:正常情况:情况⼆: 同⼀个⽅法被多个Aspect类拦截此处举例为被两个aspect类拦截。
Spring系列之AOP实现的两种方式
Spring系列之AOP实现的两种⽅式Spring只⽀持XML⽅式⽽没有实现注解的⽅式(也叫AspectJ⽅式)的AOP,所以要使⽤@Aspect注解,只能引⼊AspectJ相关的 jar 包:aopalliance-1.0.jar 和 aspectjweaver.jarSpring的配置⽂件 applicationContext.xml 中引⼊context、aop对应的命名空间;配置⾃动扫描的包,同时使切⾯类中相关⽅法中的注解⽣效,需⾃动地为匹配到的⽅法所在的类⽣成代理对象。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:aop="/schema/aop"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd/schema/aop /schema/aop/spring-aop-4.0.xsd/schema/context /schema/context/spring-context-4.0.xsd"><!-- 配置⾃动扫描的包 --><context:component-scan base-package="com.qcc.beans.aop"></context:component-scan><!-- ⾃动为切⾯⽅法中匹配的⽅法所在的类⽣成代理对象。
--><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>AOP常⽤的实现⽅式有两种,1、采⽤声明的⽅式来实现(基于XML),2、是采⽤注解的⽅式来实现(基于AspectJ)。
ioc和aop底层实现原理
ioc和aop底层实现原理IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的核心特性,它们在底层实现原理上有各自的特点。
1. IoC原理:IoC是Spring框架的核心概念之一,其基本原理是将对象的创建、初始化、销毁等控制权交给Spring容器来管理,而不再由开发者直接操作。
这样,开发者只需要关注业务逻辑,而不需要关注对象的创建和销毁等细节。
在Spring中,IoC是通过依赖注入(Dependency Injection)实现的。
依赖注入有两种方式:构造器注入:通过构造器的方式将依赖注入到对象中。
属性注入:通过Setter方法或直接赋值的方式将依赖注入到对象中。
Spring容器负责管理Bean的生命周期,包括实例化、属性设置、依赖注入、初始化、销毁等。
在运行时,Spring容器会根据配置文件或注解等方式,自动完成Bean的创建和依赖注入。
2. AOP原理:AOP是Spring框架中的另一个核心概念,它主要关注的是将应用程序中的切面进行抽象和统一管理。
通过AOP,可以将一些通用逻辑(如日志记录、事务管理等)从业务逻辑中分离出来,实现模块化、可复用的代码结构。
在Spring中,AOP通过动态代理实现,其核心组件是切面(Aspect)。
一个切面可以包含多个通知(Advice),每个通知都对应一个特定的方法。
这些通知可以是前置通知(Before)、后置通知(After)、异常抛出通知(AfterThrowing)等。
当一个方法被调用时,Spring会根据配置自动代理该方法,并执行相应的通知。
代理对象会拦截到该方法的调用,并执行相应的通知逻辑。
这样,开发者只需要关注业务逻辑,而不需要手动编写代理代码。
总结:IoC和AOP是Spring框架的核心特性,它们通过不同的方式实现了解耦和模块化。
IoC关注的是对象的创建和生命周期管理,而AOP关注的是将通用逻辑从业务逻辑中分离出来。
Spring面试,IoC和AOP的理解,@Transactional原理及使用
Spring⾯试,IoC和AOP的理解,@Transactional原理及使⽤spring 的优点?1.降低了组件之间的耦合性,实现了软件各层之间的解耦2.可以使⽤容易提供的众多服务,如事务管理,消息服务等3.容器提供单例模式⽀持4.容器提供了AOP技术,利⽤它很容易实现如权限拦截,运⾏期监控等功能5.容器提供了众多的辅助类,能加快应⽤的开发6.spring对于主流的应⽤框架提供了集成⽀持,如hibernate,JPA,Struts等7.spring属于低侵⼊式设计,代码的污染极低8.独⽴于各种应⽤服务器9.spring的DI机制降低了业务对象替换的复杂性10.Spring的⾼度开放性,并不强制应⽤完全依赖于Spring,开发者可以⾃由选择spring的部分或全部什么是DI机制?依赖注⼊(Dependecy Injection)和控制反转(Inversion of Control)是同⼀个概念,具体的讲:当某个⾓⾊需要另外⼀个⾓⾊协助的时候,在传统的程序设计过程中,通常由调⽤者来创建被调⽤者的实例。
但在spring中创建被调⽤者的⼯作不再由调⽤者来完成,因此称为控制反转。
创建被调⽤者的⼯作由spring来完成,然后注⼊调⽤者因此也称为依赖注⼊。
spring以动态灵活的⽅式来管理对象,注⼊的两种⽅式,设置注⼊和构造注⼊。
设置注⼊的优点:直观,⾃然构造注⼊的优点:可以在构造器中决定依赖关系的顺序。
什么是AOP?⾯向切⾯编程(AOP)完善spring的依赖注⼊(DI),⾯向切⾯编程在spring中主要表现为两个⽅⾯1.⾯向切⾯编程提供声明式事务管理2.spring⽀持⽤户⾃定义的切⾯⾯向切⾯编程(aop)是对⾯向对象编程(oop)的补充,⾯向对象编程将程序分解成各个层次的对象,⾯向切⾯编程将程序运⾏过程分解成各个切⾯。
AOP从程序运⾏⾓度考虑程序的结构,提取业务处理过程的切⾯,oop是静态的抽象,aop是动态的抽象,是对应⽤执⾏过程中的步骤进⾏抽象,,从⽽获得步骤之间的逻辑划分。
springaop面试题
springaop面试题
一、面试官问:AOP是什么?
与OOP对比,面向切面,传统的OOP开发中的代码逻辑是至上而下的过程中会长生一些横切性问题,这些横切性的问题和我们的主业务逻辑关系不会散落在代码的各个地方,造成难以维护,AOP的编程思想就是把业务逻辑和横切的问题进行分离,从而达到解耦的目的,使代码的重用性和开发效率高(目的是重用代码,把公共的代码抽取出来)。
二、面试官问:AOP的应用场景有哪些呢?
1、日志记录;
2、权限验证;
3、效率检查(个人在代码上,喜欢用注解+切面,实现校验,redis 分布式锁等功能);
4、事务管理(spring的事务就是用AOP实现的);
三、面试官问:springAop的底层是怎样实现的?
1、JDK动态代理;
2、CGLIB代理;
四、面试官问:springAOP和AspectJ的关系?
1、两者都是为了实现AOP这个目的,而出现的技术,springaop 参考AspectJ编程风格。
SpringAOP切点表达式用法总结
SpringAOP切点表达式⽤法总结1. 简介⾯向对象编程,也称为OOP(即Object Oriented Programming)最⼤的优点在于能够将业务模块进⾏封装,从⽽达到功能复⽤的⽬的。
通过⾯向对象编程,不同的模板可以相互组装,从⽽实现更为复杂的业务模块,其结构形式可⽤下图表⽰:⾯向对象编程解决了业务模块的封装复⽤的问题,但是对于某些模块,其本⾝并不独属于摸个业务模块,⽽是根据不同的情况,贯穿于某⼏个或全部的模块之间的。
例如登录验证,其只开放⼏个可以不⽤登录的接⼝给⽤户使⽤(⼀般登录使⽤拦截器实现,但是其切⾯思想是⼀致的);再⽐如性能统计,其需要记录每个业务模块的调⽤,并且监控器调⽤时间。
可以看到,这些横贯于每个业务模块的模块,如果使⽤⾯向对象的⽅式,那么就需要在已封装的每个模块中添加相应的重复代码,对于这种情况,⾯向切⾯编程就可以派上⽤场了。
⾯向切⾯编程,也称为AOP(即Aspect Oriented Programming),指的是将⼀定的切⾯逻辑按照⼀定的⽅式编织到指定的业务模块中,从⽽将这些业务模块的调⽤包裹起来。
如下是其结构⽰意图:2. AOP的各个扮演者2.1 AOP的主要⾓⾊切⾯:使⽤切点表达式表⽰,指定了当前切⾯逻辑所要包裹的业务模块的范围⼤⼩;Advice:也即切⾯逻辑,指定了当前⽤于包裹切⾯指定的业务模块的逻辑。
2.2 Advice的主要类型@Before:该注解标注的⽅法在业务模块代码执⾏之前执⾏,其不能阻⽌业务模块的执⾏,除⾮抛出异常;@AfterReturning:该注解标注的⽅法在业务模块代码执⾏之后执⾏;@AfterThrowing:该注解标注的⽅法在业务模块抛出指定异常后执⾏;@After:该注解标注的⽅法在所有的Advice执⾏完成后执⾏,⽆论业务模块是否抛出异常,类似于finally的作⽤;@Around:该注解功能最为强⼤,其所标注的⽅法⽤于编写包裹业务模块执⾏的代码,其可以传⼊⼀个ProceedingJoinPoint⽤于调⽤业务模块的代码,⽆论是调⽤前逻辑还是调⽤后逻辑,都可以在该⽅法中编写,甚⾄其可以根据⼀定的条件⽽阻断业务模块的调⽤;@DeclareParents:其是⼀种Introduction类型的模型,在属性声明上使⽤,主要⽤于为指定的业务模块添加新的接⼝和相应的实现。
SpringAOP相关的几道面试题
SpringAOP相关的⼏道⾯试题1. 说出Spring的通知类型有哪些?2. 谈谈⽬标对象实现接⼝与⽬标对象不实现接⼝有什么区别?3. 请描述JDK动态代理和CGLI代理的区别?4. 简述ProxyFactoryBean的作⽤是什么?5. 叙述Spring中的⾃动代理的原理?5. 写出创建代理对象需指定的三要素是什么?6. 写出代理的两种⽅式分别是什么?7. 请简述:什么是AOP?8. 简述AOP核⼼?9. 请叙述AOP事务的含义?1. 下⾯关于spring描述错误的是:()A Spring⽀持可插⼊的事务管理器,使事务划分更轻松,同时⽆需处理底层的问题。
B Spring事务管理的通⽤抽象层还包括JTA策略和⼀个JDBC DataSource。
C 与JTA或EJB CMT⼀样,Spring的事务⽀持依赖于Java EE环境。
D Spring事务语义通过AOP应⽤于 POJO,通过XML或Java SE 5注释进⾏配置。
2. 下⾯选项哪个不是Spring中接⼝注⼊的⽅式?()A 接⼝注⼊ B 构造⼦注⼊ C 设值注⼊ D 指针注⼊3. 下列关于Spring特性中IoC描述错误的是:()A IoC就是指程序之间的关系由程序代码直接操控。
B 所谓“控制反转”,是指控制权由应⽤代码转到外部容器,控制权的转移,C IoC将控制创建的职责搬进了框架中;并把它从应⽤代码脱离开来D 当使⽤Spring的IoC容器时只需指出组件需要的对象,在运⾏时Spring的IoC容器会根据XML配置数据提供给它。
简答题:1. 请简述Spring的⼯作机制?2. 请回答你为什么⽤Spring的⼯作机制?3. 请简述Spring是什么?4. 简述spring的组成?5.简述Spring容器提供了哪些功能?6. 在Spring中,bean的注⼊有⼏种⽅式,各是什么?7. 请简述:Spring bean的作⽤域?8. 请叙述设值注⼊的优点?9. 请叙述构造注⼊的优点?10. 说出bean⼯⼚创建bean的三种⽅式?a11. 请写出bean的⽣命周期的⽅法?12. 请简述你对IOC的理解?13. 请回答:IoC最⼤的好处是什么?14. 简述IoC的类型?15. Spring中依赖注⼊与传统编程之间的差别是什么?。
Spring框架之IOC和AOP底层原理
Spring框架之IOC和AOP底层原理<!-- https:///artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.6.RELEASE</version></dependency><!-- https:///artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.6.RELEASE</version></dependency>1.2优点:Spring是⼀个开源的免费的框架(容器)Spring是⼀个轻量级、⾮⼊侵式的框架控制反转(IOC)、⾯向切⾯编程(AOP)⽀持事务的处理,对框架整合的⽀持总结⼀句话:Spring就是⼀个轻量级的控制反转(IOC),和⾯向切⾯编程(AOP)的框架1、3组成1、4拓展Spring官⽹:现代化的开发就是基于java的开发Spring Boot⼀个快速开发的脚⼿架基于SpringBoot可以快速开发单个微服务约定⼤于配置Spring CloudSpringCloud是基于SpringBoot实现的因为现在⼤多数公司都在使⽤SprigBoot进⾏快速开发,学习SpringBoot的前提,需要完全掌握Spring以及SpringMVC!弊端:Spring发展太久,违背了原来的理念!配置⼗分繁琐,⼈称“配置地狱”!2、IOC理论推导1、UserDao接⼝public interface UserDao {void getUser();}2、UserDaoImpl实现类public class UserDaoImpl implements UserDao {public void getUser() {System.out.println("默认获取⽤户的数据");}}3、UserService接⼝public interface UserService {void getUser();}4、UserServiceImpl业务实现类public class UserServiceImpl implements UserService {private UserDao userDao ;//利⽤Set接⼝进⾏动态实现注⼊public void setUserDao(UserDao userDao) {erDao = userDao;}public void getUser() {userDao.getUser();}}在之前的业务中,⽤户的额需求可能会影响到我们原来的代码,我们需要根据⽤户的需求去修改源代码!如果程序代码量⼗分⼤,修改⼀次的成本代价⼗分昂贵!我们使⽤⼀个Set接⼝实现,已经发⽣了⾰命性的改变!//利⽤Set接⼝进⾏动态实现注⼊public void setUserDao(UserDao userDao) {erDao = userDao;}之前,程序是主动创建对象!控制权在程序员⼿上!使⽤了Set注⼊后,程序不再具有主动性,⽽是变成了被动的接收对象这种思想,从本质上解决了问题,我们程序员不⽤再去管理对象的创建了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【Spring之AOP】什么是AOP?-面向切面编程-它是一种思想,可在不改变程序源码的情况下为程序添加额外的功能。
-允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发。
应用对象只实现业务逻辑即可,并不负责其他的系统级关注点。
-AOP专门用于处理系统中分布于各个模块中的交叉关注点的问题,在J2EE应用中,常常通过AOP来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等,AOP已经成为一种非常常用的解决方案。
AOP的发展过程?-静态AOP:Aspect形式,通过特定的编译器,将实现后的Aspect编译并织入到系统的静态类中-动态AOP:AOP的织入过程在系统运行开始之后进行,而不是预先编译到系统中AOP术语?-连接点:程序执行的某个特定位置,比如类初始化前、类初始化后、方法调用前、方法调用后等-切点:通过切点来定位特定的连接点-增强:织入到目标类连接点上的一段程序代码-目标对象:增强逻辑的织入目标类-引介:是一种特殊的增强,它为类添加一些属性和方法-织入:为增强添加目标类的具体连接点上的过程-代理:一个类被AOP织入增强后,会产生一个结果类,该类融合了原类和增强逻辑的代理类-切面:由切点和增强组成,既包括了横切逻辑的定义,也包括了连接点的定义AOP的原理剖析?-AOP代理其实是由AOP框架动态生成的一个对象,该对象可作为目标对象使用,AOP代理所包含的方法与目标对象的方法如下图所示:使用AOP的步骤是:定义普通业务组件--->定义切入点--->定义增强处理代理对象的方法= 增强处理+ 被代理对象的方法AOP的通俗理解?-一个组件A,不关心其他常用的服务组件B,但是这个组件A使用组件B的时候,不是组件A自身去调用,而是通过配置等其他方式,比如Spring中可以通过xml配置文件。
这样就使得A压根就不需要知道服务组件B是怎样的,爱存在不存在,爱怎么存在都与A无关。
A只关心自己的业务逻辑,具体A使用B的时候,配置文件去做,与具体的A组件无关。
AOP的实现方法?(1)利用Proxy实现AOP功能(JDK动态代理)采用Proxy类方法,基本流程为:主函数--->代理--->目标对象的方法。
对于Proxy类有一个使用前提,就是目标对象必须实现接口,否则不能使用这个方法。
实现AOP功能步骤如下:创建接口:StudentInterface.java创建接口实现类:StudentBean.java创建代理工厂:ProxyFactory.java[java]view plain copy1.public interface StudentInterface {2.3.public void print();4.5.}[java]view plain copy1.public class StudentBean implements StudentInterface {2.3.private String name;4.5.public String getName() {6.return name;7. }8.9.public void setName(String name) { = name;11. }12.13.public StudentBean() {14. }15.16.public StudentBean(String name) {17.super(); = name;19. }20.21.@Override22.public void print() {23. System.out.println("hi student.");24. }25.26.}[java]view plain copy1.public class ProxyFactory implements InvocationHandler {2.3.private Object object;4.5.public Object createStudentProxy(Object obj) {6.this.object = obj;7.//创建并返回代理8.return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj9. .getClass().getInterfaces(), this);10. }11.12.@Override13.public Object invoke(Object proxy, Method method, Object[] args)14.throws Throwable {15. StudentBean studentBean = (StudentBean) object;16. Object obj = null;17.if(studentBean.getName() != null){18. obj = method.invoke(object, args);19. }else{20. System.out.println("学生姓名为空,代理类已经进行拦截.");21. }22.return obj;23. }24.25.}[java]view plain copy1.public class Test001 {2.3.public static void main(String[] args) {4. StudentInterface s1 = new StudentBean();5. ProxyFactory proxyFactory = new ProxyFactory();6. StudentInterface s2 = (StudentInterface) proxyFactory7. .createStudentProxy(s1);8. s2.print();9. }10.}总结:目标对象必须实现接口返回创建的代理对象重写invoke()方法限制条件放在invoke()方法中(2)利用CGLIB实现AOP功能(CGLIB动态代理)CGLIB(code generation library)是一个开源项目,它是一个强大的、高性能、高质量的code生成类库,它可以在运行期间扩展Java类和实现Java接口。
实现AOP功能步骤如下所示:引入jar包创建实体类创建CGLIB代理类创建入口类进行测试[java]view plain copy1.public class StudentBean {2.3.private String name;4.5.public String getName() {6.return name;7. }8.9.public void setName(String name) { = name;11. }12.13.public StudentBean() {14. }15.16.public StudentBean(String name) {17.super(); = name;19. }20.21.public void print() {22. System.out.println("hi student.");23. }24.25.}[java]view plain copy1.public class CGLIBProxyFactory implements MethodInterceptor{2.3.private Object object;4.5.public Object createStudentProxy(Object obj){6.this.object = obj;7. Enhancer enhancer = new Enhancer();8. enhancer.setSuperclass(obj.getClass());9. enhancer.setCallback(this);10.return enhancer.create();11. }12.13.14.@Override15.public Object intercept(Object proxy, Method method, Object[] args,16. MethodProxy methodProxy) throws Throwable {17. StudentBean stu = (StudentBean) object;18. Object ret = null;19.if(stu.getName() != null){20. methodProxy.invoke(object, args);21. }else{22. System.out.println("学生姓名为空,方法已经被拦截.");23. }24.return ret;25. }26.27.}[java]view plain copy1.public class Test002 {2.3.public static void main(String[] args) {4.5. StudentBean s1 = new StudentBean();6. CGLIBProxyFactory cglibProxyFactory = new CGLIBProxyFactory();7. StudentBean s2 = (StudentBean) cglibProxyFactory.createStudentProxy(s1);8. s2.print();9.10. }11.12.}(3)利用Spring XML文件配置方式实现AOP功能步骤如下:引入jar包配置AOP命名空间创建目标对象类创建切面在配置文件中配置创建入口类进行测试[java]view plain copy1.public interface TrainStationAware {2.3.//售票方法4.public String sellTicket(String name);5.6.//退票方法7.public String returnTicket(String name);8.}[java]view plain copy1.public class TrainStation implements TrainStationAware{2.3.@Override4.public String sellTicket(String name) {5. System.out.println(name + "购票成功");6.return"ok";7.8. }9.10.@Override11.public String returnTicket(String name) {12. System.out.println(name + "退票成功");13.return"ok2";14. }15.16.}[java]view plain copy1.public class XmlAdvice {2.3./**4. * 在核心业务执行前执行,不能阻止核心业务的调用。