AOP是什么?
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面编程。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP能够说也是这种目标的一种实现。
面向方面编程 AOP(Aspect Oriented Programming)是一种“关注点(Concern)”分离技术,经过运用“方面(aspect)”这种程序设计单元,容许开发者使用结构化的设计和编码,反映出其对系统的认识方式。AOP使设计和编码更加模块化、更加具结构化,从而使关注点局部化而不是分散于整个系统中。同时,须要定义好关注点和系统其余部分的接口,从而真正达到“分离关注点,分而治之”的目的。spring
一、AOP终级目标
AOP终级目标就是能以更天然、更灵活的方式模拟现实世界,从原始的机器语言到过程语言再到面向对象的语言,编程语言一步步地用更天然的方式描述软个把。AOP是软件开发思想的下一个产物,但AOP的出现并非要彻底代替OOP,而仅仅是做为OOP的有益补充。
二、AOP 解决紧密耦合的难题
许多 Java 开发人员已经接受了面向方面编程(AOP)的非强制性风格和灵活性,特别是在用于创建高度松散和可扩展的企业系统时
在将商业需求转换成软件功能的快速开发周期中,面向方面是一种能够利用的强有力的设计原理。经过将首要的设计重点从面向对象编程(OOP)的传统化特性转移出来,AOP 和设计原理容许软件架构师用一种和面向对象至关而又互补的方式来考虑设计。
三、分散关注 将通用需求功能从不相关类之中分离出来;同时,可以使得不少类共享一个行为,一旦行为发生变化,没必要修改不少类,只要修改这个行为就能够。
四、AOP超越面向对象编程和设计,正在成为软件开发的下一个圣杯。
使用AOP,你能够将处理aspect的代码注入主程序,一般主程序的主要目的并不在于处理这些aspect。AOP能够防止代码混乱。
AOP 与全部 Java 开发人员所使用的面向对象设计和编程并不矛盾,也不会替代它,相反,会对其给予补充。AOP 能够当作开发人员和研究团体超越软件工程中的面向对象编程(OOP)天然而然的下一步。 数据库
Aspect(切面): 是通知和切入点的结合,通知和切入点共同定义了关于切面的所有内容---它的功能、在什么时候和何地完成其功能
joinpoint(链接点):所谓链接点是指那些被拦截到的点。在spring中,这些点指的是方法,由于spring只支持方法类型的链接点.
Pointcut(切入点):所谓切入点是指咱们要对那些joinpoint进行拦截的定义.
通知定义了切面的”什么”和”什么时候”,切入点就定义了”何地”.
Advice(通知):所谓通知是指拦截到joinpoint以后所要作的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Target(目标对象):代理的目标对象
Weaving(织入):是指把切面应用到目标对象来建立新的代理对象的过程.切面在指定的链接点织入到目标对象
Introduction(引入):在不修改类代码的前提下, Introduction能够在运行期为类动态地添加一些方法或Field.express
代码实例:编程
1)新建Book的pojo类设计模式
package com.spring._0416service; public class Book { private String bookeName; private String author; private double price; public Book() { } public String getBookeName() { return bookeName; } public void setBookeName(String bookeName) { this.bookeName = bookeName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } }
2)这里模拟数据库的新增方法架构
package com.spring._0416service; public interface BookService { public void addBook(Book book); } package com.spring._0416service; public class BookServiceImpl implements BookService{ @Override public void addBook(Book book) { System.out.println(book.getBookeName()+" "+book.getAuthor()+" "+book.getPrice()); } }
3)准备事务切面类app
package com.spring._0416service; /** * 事务切面类 * */ public class TransAspect { public void open(){ System.out.println("开启事务"); } public void commit(){ System.out.println("提交事务"); } }
4)配置applicationContext.xml编程语言
1.注入bookService和transAspectide
<bean id="bookService" class="com.spring._0416service.BookServiceImpl"/> <bean id="transAspect" class="com.spring._0416service.TransAspect"/>
2.配置切面 (前置通知和后置通知)模块化
<!--配置切面--> <aop:config> <!--order 用来多个排序--> <aop:aspect order="1" ref="transAspect"> <!--第一颗*表明任意返回值类型,第三颗*表明类的任意方法,两个.表明 任意参数--> <aop:pointcut id="cutPoint" expression="execution(* com.spring._0416service.*.*(..))"/> <aop:before method="open" pointcut-ref="cutPoint"/> <aop:after method="commit" pointcut-ref="cutPoint"/> </aop:aspect> </aop:config>
5)测试
import com.spring._0416service.Book; import com.spring._0416service.BookService; import com.spring._0416service.BookServiceImpl; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BookServiceTest { private BookService bookService; @Before public void init(){ ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml"); bookService=act.getBean("bookService",BookService.class); } @Test public void test(){ Book book=new Book(); book.setAuthor("海明威"); book.setBookeName("丧钟为谁而鸣"); bookService.addBook(book); } }
结果:
1)新建user的pojo类
package com.spring.homework1; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
2)service两个方法:查看view()方法和删除delete()方法
package com.spring.homework1; public interface UserService { public void view(User user); public void delete(User user); } package com.spring.homework1; public class UserServiceImpl implements UserService{ public void view(User user) { System.out.println(user.getUsername()+"查看该网站"); } public void delete(User user) { System.out.println(user.getUsername()+"执行删除"); } }
3)设置两个切面类(getArgs()方法:获取链接点方法运行时的入参列表,proceed()方法:经过反射执行目标对象的链接点处的方法,就是放行的意思)
package com.spring.homework1; import org.aspectj.lang.ProceedingJoinPoint; public class UserAspect1 { public Object check1(ProceedingJoinPoint point) throws Throwable { Object result=null; User user= (User) point.getArgs()[0]; if(user.getUsername().equals("ling")&&user.getPassword().equals("wutongshu")){ result= point.proceed(); System.out.println("当前的方法:"+point.getSignature().getName()+" check1"); }else if(user.getUsername().equals("miao")&&user.getPassword().equals("wutongshu")){ System.out.println("当前的方法:"+point.getSignature().getName()+" check1"); result=point.proceed(); }else{ System.out.println("sss权限不够,请从新登陆"); System.out.println("当前的方法:"+point.getSignature().getName()+"check1"); } return result; } }
package com.spring.homework1; import org.aspectj.lang.ProceedingJoinPoint; public class UserAspect2 { public Object check2(ProceedingJoinPoint point) throws Throwable { Object result=null; User user= (User) point.getArgs()[0]; if(user.getUsername().equals("ling")&&user.getPassword().equals("wutongshu")){ System.out.println("当前的方法:"+point.getSignature().getName()+"check2"); result= point.proceed(); }else if(user.getUsername().equals("miao")&&user.getPassword().equals("wutongshu")){ System.out.println("当前的方法:"+point.getSignature().getName()+"check2"); System.out.println("权限不够,没法删除"); }else{ System.out.println("ss权限不够,请从新登陆"); System.out.println("当前的方法:"+point.getSignature().getName()+"check2"); } return result; } }
4)配置xml (around 环绕通知)
<bean id="userService" class="com.spring.homework1.UserServiceImpl"/> <bean id="userAspect1" class="com.spring.homework1.UserAspect1"/> <bean id="userAspect2" class="com.spring.homework1.UserAspect2"/> <aop:config> <aop:aspect order="1" ref="userAspect1"> <aop:pointcut id="user1Point" expression="execution(* com.spring.homework1.UserServiceImpl.view(..))"/> <aop:around method="check1" pointcut-ref="user1Point"/> </aop:aspect> <aop:aspect order="2" ref="userAspect2"> <aop:pointcut id="user2Point" expression="execution(* com.spring.homework1.UserServiceImpl.delete(..))"/> <aop:around method="check2" pointcut-ref="user2Point"/> </aop:aspect> </aop:config>
5)测试
import com.spring.homework1.User; import com.spring.homework1.UserService; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserServiceTest { private UserService userService; @Before public void init(){ ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml"); userService=act.getBean("userService",UserService.class); } @Test public void test(){ User user=new User(); user.setUsername("ling"); user.setPassword("wutongshu"); userService.view(user); userService.delete(user); } }
结果:
当咱们切换成只能查看的用户
或者二者权限都没有的用户