网站内容全屏截屏怎么做,微网站自助建站后台,软件外包公司是什么意思,交通局网站建设方案面向切面编程简介
IoC使软件组件松耦合。AOP让你能够捕捉系统中经常使用的功能#xff0c;把它转化成组件。
AOP#xff08;Aspect Oriented Programming#xff09;#xff1a;面向切面编程#xff0c;面向方面编程。#xff08;AOP是一种编程技术#xff09;
AOP是对…面向切面编程简介
IoC使软件组件松耦合。AOP让你能够捕捉系统中经常使用的功能把它转化成组件。
AOPAspect Oriented Programming面向切面编程面向方面编程。AOP是一种编程技术
AOP是对OOP的补充延伸。
AOP底层使用的就是动态代理来实现的。
Spring的AOP使用的动态代理是JDK动态代理 CGLIB动态代理技术。Spring在这两种动态代理中灵活切换如果是
代理接口会默认使用JDK动态代理如果要代理某个类这个类没有实现接口就会切换使用CGLIB。当然你
也可以强制通过一些配置让Spring只使用CGLIB。AOP介绍
一般一个系统当中都会有一些系统服务例如日志、事务管理、安全等。这些系统服务被称为交叉业务 这些交叉业务几乎是通用的不管你是做银行账户转账还是删除用户数据。日志、事务管理、安全这些都是需要做的。 如果在每一个业务处理过程当中都掺杂这些交叉业务代码进去的话存在两方面问题 ● 第一交叉业务代码在多个业务流程中反复出现显然这个交叉业务代码没有得到复用。并且修改这些交叉业务代码的话需要修改多处。 ● 第二程序员无法专注核心业务代码的编写在编写核心业务代码的同时还需要处理这些交叉业务。 使用AOP可以很轻松的解决以上问题。
用一句话总结AOP将与核心业务无关的代码独立的抽取出来形成一个独立的组件然后以横向交叉的方式应用到业务流程当中的过程被称为AOP。 AOP的优点 ● 第一代码复用性增强。 ● 第二代码易维护。 ● 第三使开发者更关注业务逻辑。
AOP的七大术语
● 连接点 Joinpoint 在程序的整个执行流程中可以织入切面的位置。方法的执行前后异常抛出之后等位置。 ● 切点 Pointcut 在程序执行流程中真正织入切面的方法。一个切点对应多个连接点 ● 通知 Advice 通知又叫增强就是具体你要织入的代码。 ○ 通知包括 前置通知 后置通知 环绕通知 异常通知 最终通知 ● 切面 Aspect 切点 通知就是切面。 ● 织入 Weaving 把通知应用到目标对象上的过程。 ● 代理对象 Proxy 一个目标对象被织入通知后产生的新对象。 ● 目标对象 Target 被织入通知的对象。 切点表达式
切点表达式用来定义通知Advice往哪些方法上切入。 切入点表达式语法格式 execution([访问控制权限修饰符] 返回值类型 [全限定类名]方法名(形式参数列表) [异常]) 访问控制权限修饰符 可选项。 ● 没写就是4个权限都包括。 ● 写public就表示只包括公开的方法。 返回值类型 ● 必填项。 ● * 表示返回值类型任意。 全限定类名 ● 可选项。 ● 两个点“…”代表当前包以及子包下的所有类。 ● 省略时表示所有的类。 方法名 ● 必填项。 ● 表示所有方法。 ● set表示所有的set方法。 形式参数列表 ● 必填项 ● () 表示没有参数的方法 ● (…) 参数类型和个数随意的方法 ● () 只有一个参数的方法 ● (, String) 第一个参数类型随意第二个参数是String的。 异常 ● 可选项。 ● 省略时表示任意异常类型。 使用Spring的AOP
Spring对AOP的实现包括以下3种方式
第一种方式Spring框架结合AspectJ框架实现的AOP基于注解方式。
第二种方式Spring框架结合AspectJ框架实现的AOP基于XML方式。
第三种方式Spring框架自己实现的AOP基于XML配置方式。开发中主要使用前两种为了更好理解其原理下面分析第二种方式。即基于XML的方式日志信息案例,全注解形式
准备工作(基于maven的开发)
引入依赖
!--spring context依赖--
dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion6.0.0-M2/version
/dependency
!--spring aop依赖--
dependencygroupIdorg.springframework/groupIdartifactIdspring-aop/artifactIdversion6.0.0-M2/version
/dependency
!--spring aspects依赖--
dependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion6.0.0-M2/version
/dependency通知类准备(里面写通知的代码)
public class LogAspect {public void beforeAdvice(JoinPoint joinPoint){SimpleDateFormat sdf new SimpleDateFormat(yyyy-MM-dd HH-mm-ss SSS);String nowTime sdf.format(new Date());System.out.println(nowTime chu: joinPoint.getSignature().getDeclaringTypeName() . joinPoint.getSignature().getName());}
}具体业务代码准备
public class UserService {public void getUser(){System.out.println(获取用户信息...);}public void addUser(){System.out.println(增添用户...);}public void deleteUser(){System.out.println(删除用户...);}public void modifyUser(){System.out.println(修改用户信息...);}}
前提工作做完下面就是配置工作 spring配置文件代码
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd!-- 将通知类和业务类纳入spring管理--bean idlogAspect classcom.hkd.spring.biz.LogAspect/bean iduserService classcom.hkd.spring.biz.UserService/aop:config
!-- 设置切点--aop:pointcut idlogPointcut expressionexecution(* com.hkd.spring.biz.UserService.*(..))/
!-- 设置切面切面 切点 通知
--aop:aspect reflogAspect
!-- 测试前置通知--aop:before methodbeforeAdvice pointcut-reflogPointcut//aop:aspect/aop:config/beans接下来写测试代码测试功能 Testpublic void testLogAspect(){ApplicationContext applicationContext new ClassPathXmlApplicationContext(spring.xml);com.hkd.spring.biz.UserService userService applicationContext.getBean(userService, com.hkd.spring.biz.UserService.class);userService.addUser();userService.getUser();userService.deleteUser();userService.modifyUser();}运行结果 可见在每个方法执行之前都有相关日志信息测试成功
Spring框架结合AspectJ框架实现的AOP基于注解方式(安全日志案例)
配置文件准备
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
//该标记说明该类是取代xml文件的配置文件
Configuration
//扫描该包下的类并令其归于spring容器管理
ComponentScan(com.hkd.spring6.safe)
//开启自动代理含有Aspect标签的类自动生成代理类
EnableAspectJAutoProxy
public class SpringConfiguration2 {
}Service业务类准备
package com.hkd.spring6.safe;import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Service;Service(userService)
public class UserService {public void getUser(){System.out.println(正在获取用户信息...);}public void saveUser(){System.out.println(正在保存用户信息...);}public void deleteUser(){System.out.println(正在删除用户信息...);}public void modifyUser(){System.out.println(正在修改用户信息...);}
}
package com.hkd.spring6.safe;import org.springframework.stereotype.Service;Service(productService)
public class ProductService {public void getProduct(){System.out.println(正在获取商品信息...);}public void saveProduct(){System.out.println(正在保存商品信息...);}public void deleteProduct(){System.out.println(正在删除商品信息...);}public void modifyProduct(){System.out.println(正在修改商品信息...);}}
切面类
package com.hkd.spring6.safe;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;Component
Aspect
public class SecurityAspect {// 切点切点表达式的优化使用方法下面再使用该切点表达式只需要调用该方法即可Pointcut(execution(* com.hkd.spring6.safe..save*(..)))public void savePointcut(){}Pointcut(execution(* com.hkd.spring6.safe..delete*(..)))public void deletePointcut(){}Pointcut(execution(* com.hkd.spring6.safe..modify*(..)))public void modifyPointcut(){}// 切面 切点 通知Before(savePointcut() || deletePointcut() || modifyPointcut())public void beforeAdvice(JoinPoint joinPoint){System.out.println(chu操作员正在操作 joinPoint.getSignature().getName() 方法);}}
测试代码
Testpublic void testSecurity2(){ApplicationContext applicationContext new AnnotationConfigApplicationContext(SpringConfiguration2.class);com.hkd.spring6.safe.UserService userService applicationContext.getBean(userService, com.hkd.spring6.safe.UserService.class);com.hkd.spring6.safe.ProductService productService applicationContext.getBean(productService, com.hkd.spring6.safe.ProductService.class);userService.getUser();userService.deleteUser();userService.modifyUser();userService.saveUser();productService.getProduct();productService.deleteProduct();productService.modifyProduct();productService.saveProduct();}测试结果