springboot开启全局热部署和切面编程
1、在不重新启动程序(服务器)就可以将代码的修改立即生效的热部署过程(原理就是配置了俩个类加载器,相互切换。也又代价,启动会慢,因为现在要维护俩个类加载器)
2、springboot官方提供了俩种方式
a.springboot-devtools 第一种方式
b.spring-loaded 第二种方式,有时候不生效
c.jrebel 第三方形式 jvm内存占用少 修改之后立即生效无需等待 价格很贵
3、springboot如何开启全局热部署
a)引入依赖
<!-- 热部署的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
b).开启idea的自动编译功能
在Compiler中勾选Build project automatically
c).开启idea中允许在程序运行过程允许交换器类加载
ctrl+alt+shift+/ 选择1.Registry—-》勾选compiler.automake.allow.when.app.running这个选项
d).重新启动项目即可
二:springboot中切面编程
1.Spring提出AOP面向切面编程
AOP:就是通过动态为项目中某些类在运行过程中动态创建代理对象,然后再代理对象中完成附加功能和额外功能。保证再处理业务时更专注于自己得业务逻辑开发。
概念:
1).通知(advice) 除了目标方法以外操作称之为通知 日志通知 性能通知 事务通知…..
2). 切入点(pointcut):用来告诉项目中那些类中那些方法在执行过程中加入通知
3)切面(Aspect):通知 +切入点
spring中AOP编程
1).前置通知,后置通知,环绕通知,异常通知
2).配置通知并组装切面
<bean id class=”xxxxxx”>
<aop:config>
<aop:pointcut expression = “exection()|within | annotation|args”>
<aop: advisor advice-ref=”” pointcut-ref=”” order=“1”>
<aop: advisor advice-ref=”” pointcut-ref=”” order=“2”> 这里得order值越小得越先执行 数字相同,配置先行
<aop: advisor advice-ref=”” pointcut-ref=”” order=“2”>
</aop:config>
springboot中得切面编程
a.引入spring-boot-starter-aop
面向切面编程相关注解:
@Aspect 注解 :修饰范围在一个类上 作用:代表这个类是一个切面得配置类,相当aop:config标签
@order注解 :修饰范围只能用在类上 作用:用来控制多个切面执行顺序 value属性:int类型 数字越小越优先执行 (所以要想不同就必须重新写一个类文件)
通知相关注解:
修饰范围:用在方法上 作用:代表这个方法是一个通知方法
value属性:用来书写当前通知对应得切入点表达式
@Before 前置通知
//这是一个切面配置类 @Component @Aspect public class MyAspect { //前置通知 // @Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))") @Before(value="within(com.chinaunicom.service.*ServiceImpl)")
public void before147(JoinPoint joinPoint){
System.out.println("当前执行方法名:"+joinPoint.getSignature().getName());
System.out.println("当前执行方法参数:"+joinPoint.getArgs()[0]);
System.out.println("目标对象target:"+joinPoint.getTarget());
System.out.println("===========进入前置通知==========");
} }
@After 后置通知
@Around 环绕通知
类级别得:
@Before(value="within(com.chinaunicom.service.*ServiceImpl)")
方法级别得:修饰于方法
@Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))")
@Before和@After 获取运行时方法得相关信息在自定义通知方法中加入JointPoint参数,这个参数可以得到当前运行类得很多东西。
参数1:jointpoint 获取当前执行对象 方法得参数信息 以及目标对象
//后置通知 // @Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))") // @After(value="within(com.chinaunicom.service.*ServiceImpl)") // public void after147(JoinPoint joinPoint) { // System.out.println("当前执行方法名:" + joinPoint.getSignature().getName()); // System.out.println("当前执行方法参数:" + joinPoint.getArgs()); // System.out.println("目标对象target:" + joinPoint.getTarget()); // System.out.println("===========进入后置通知=========="); // // } // //前置通知 //// @Before(value="execution(* com.chinaunicom.service..*ServiceImpl.*(..))") // @Before(value="within(com.chinaunicom.service.*ServiceImpl)") // public void before147(JoinPoint joinPoint){ // System.out.println("当前执行方法名:"+joinPoint.getSignature().getName()); // System.out.println("当前执行方法参数:"+joinPoint.getArgs()); // System.out.println("目标对象target:"+joinPoint.getTarget()); // System.out.println("===========进入前置通知=========="); // }
@Around 获取运行时方法得相关信息并且可以放行当前方法继续执行,它的参数需要再环绕通知方法中声明这个参数是ProceedingJointPoint
//环绕通知 执行目标方法之前进入环绕通知,环绕通知放行之后 才会执行目标方法 执行完成目标方法之后 再回到环绕通知 @Around("within(com.chinaunicom.service.*ServiceImpl)") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("==============目标方法执行之前进入环绕通知==================="); System.out.println("方法名:"+proceedingJoinPoint.getSignature().getName()); System.out.println("参数:"+proceedingJoinPoint.getArgs()); System.out.println("目标对象:"+proceedingJoinPoint.getTarget()); //放行目标方法 返回一个结果 try { Object proceed = proceedingJoinPoint.proceed(); //放行执行目标方法 System.out.println("==============目标方法执行之后进入环绕通知==================="); return proceed; }catch (Exception e){ System.out.println("目标方法出现异常时处理"); return null; }
springboot多个切面执行顺序
在前置通知中order越小越优先,而后置通知得话就会相反
注意:多个aop切面得执行同样是一个栈式结构,先进后出