技术笔记:Spring中的通知(Advice)和顾问(Advisor)

简介: 技术笔记:Spring中的通知(Advice)和顾问(Advisor)

在Spring中,目前我学习了几种增强的方式,和大家分享一下


之前的话:


1.AOP (Aspect Oriented Programming 面向切面编程)


在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。


面向对象编程是从【静态角度】考虑程序的结构,而面向切面编程是从【动态角度】考虑程序运行过程。


AOP底层,就是采用【动态代理】模式实现的。采用了两种代理:JDK动态代理和CGLIB动态代理。


基本术语(一些名词):


(1)切面(Aspect)


切面泛指【交叉业务逻辑】。事务处理和日志处理可以理解为切面。常用的切面有通知(Advice)与顾问(Advisor)。实际就是对主业务逻辑的一种增强。


(2)织入(Weaving)


织入是指将切面代码插入到目标对象的过程。代理的invoke方法完成的工作,可以称为织入。


(3) 连接点(JoinPoint)


连接点是指可以被切面织入的方法。通常业务接口的方法均为连接点


(4)切入点(PointCut)


切入点指切面具体织入的方法


注意:被标记为final的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。


(5)目标对象(Target)


目标对象指将要被增强的对象。即包含主业务逻辑的类的对象。


(6)通知(Advice)


通知是切面的一种实现,可以完成简单的织入功能。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是执行之后执行等。切入点定义切入的位置,通知定义切入的时间。


(7)顾问(Advisor)


顾问是切面的另一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将通知包装为更复杂切面的装配器。


AOP是一种思想,而非实现


AOP是基于OOP,而又远远高于OOP,主要是将主要核心业务和交叉业务分离,交叉业务就是切面。例如,记录日志和开启事务。


一:前置增强和后置增强


源码介绍:


1.User.java


package cn.zhang.entity;


public class User {


private Integer id; // 用户ID


private String username; // 用户名


private String password; // 密码


private String email; // 电子邮件


public Integer getId() {


return id;


}


public void setId(Integer id) {


this.id = id;


}


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;


}


public String getEmail() {


return email;


}


public void setEmail(String email) {


this.email = email;


}


}


View Code


2.IDao.java


package cn.zhang.dao;


//定义接口


import cn.zhang.entity.User;


public interface IDao {


//定义方法


public void save(User user);


}


View Code


3.UserDao.java


package cn.zhang.dao.impl;


//实现接口


import cn.zhang.dao.IDao;


import cn.zhang.entity.User;


public class UserDao implements IDao {


@Override


//实现方法


public void save(User user) {


System.out.println("save success!");


}


}


View Code


4.IUserBiz.java


package cn.zhang.biz;


//业务接口


import cn.zhang.entity.User;


public interface IUserBiz {


//待处理的方法


public void save(User user);


}


View Code


5.UserBiz.java


package cn.zhang.biz.impl;


//业务接口的实现类


import cn.zhang.biz.IUserBiz;


import cn.zhang.dao.IDao;


import cn.zhang.entity.User;


public class UserBiz implements IUserBiz {


//引入IDao接口


private IDao dao;


@Override


//实现方法


public void save(User user) {


dao.save(user);


}


//dao 属性的setter访问器,会被Spring调用,实现设值注入


public IDao getDao() {


return dao;


}


public void setDao(IDao dao) {


this.dao = dao;


}


}


View Code


6.LoggerAfter.java(后置增强)


package cn.zhang.aop;


//后置增强


import java.lang.reflect.Method;


import org.springframework.aop.AfterReturningAdvice;


public class LoggerAfter implements AfterReturningAdvice {


@Override


public void afterReturning(Object arg0, Method arg1, Object【】 arg2,


Object arg3) throws Throwable {


System.out.println("后置增强代码");


}


}


View Code


7.LoggerBefore.java(前置增强)


package //代码效果参考:http://www.jhylw.com.cn/014528317.html

cn.zhang.aop;

//前置增强


import java.lang.reflect.Method;


import org.apache.log4j.Logger;


import org.springframework.aop.MethodBeforeAdvice;


public class LoggerBefore implements MethodBeforeAdvice {


private static final Logger log = Logger.getLogger(LoggerBefore.class);


@Override


public void before(Method arg0, Object【】 arg1, Object arg2)


throws Throwable {


log.info("前置内容AAA");


System.out.println("前置增强代码");


}


}


View Code


8.applicationContext.xml(Spring配置文件)


<?xml version="1.0" encoding="UTF-8"?>


[/span>beans xmlns=""


xmlns:xsi="" xmlns:aop=""


xmlns:p=""


xsi:schemaLocation="


"

[/span>bean id="dao" class="cn.zhang.dao.impl.UserDao" />


[/span>bean id="biz" class="cn.zhang.biz.impl.UserBiz"

[/span>property name="dao" ref="dao"



[/span>bean id="loggerBefore" class="cn.zhang.aop.LoggerBefore" />



[/span>bean id="loggerAfter" class="cn.zhang.aop.LoggerAfter" />



[/span>aop:config

[/span>aop:pointcut id="pointcut"


expression="execution(public void save(cn.zhang.entity.User))" />



[/span>aop:advisor pointcut-ref="pointcut" advice-ref="loggerBefore" />


[/span>aop:advisor pointcut-ref="pointcut" advice-ref="loggerAfter" />




View Code


当然,针对AOP的配置也可以使用代理对象 ProxyFactoryBean 代理工厂bean来实现,在测试类中:IUserBiz biz=(IUserBiz)ctx.getBean("serviceProxy");



View Code


9.MyTest.java


package cn.zhang.test;


//测试类


import org.springframework.context.ApplicationContext;


import org.springframework.context.support.ClassPathXmlApplicationContext;


import cn.zhang.biz.IUserBiz;


import cn.zhang.entity.User;


public class MyTest {


public static void main(String【】 args) {


ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");


IUserBiz biz=(IUserBiz)ctx.getBean("biz");


User user=new User();


biz.save(user);


System.out.println("success!");


}


}


View Code


10.log4j.properties(日志的配置文件)


### direct log messages to stdout ###


log4j.appender.stdout=org.apache.log4j.ConsoleAppender


log4j.appender.stdout.Target=System.out


log4j.appender.stdout.layout=org.apache.log4j.PatternLayout


log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n


### direct messages to file mylog.log ###


log4j.appender.file=org.apache.log4j.FileAppender


log4j.appender.file.File=c\:mylog.log


log4j.appender.file.layout=org.apache.log4j.PatternLayout


log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n


### set log levels - for more verbose logging change 'info' to 'debug' ###


log4j.rootLogger=info, stdout


View Code


当然,别忘了引入我们需要的jar包啊!


常用的jar:


二:异常抛出增强和环绕增强


源码介绍:


1.User.java


package cn.zhang.entity;


public class User {


private Integer id; // 用户ID


private String username; // 用户名


private String password; // 密码


private String email; // 电子邮件


public User() {


super();


// TODO Auto-generated constructor stub


}


public User(Integer id, String username, String password, String email) {


super();


this.id = id;


this.username = username;


this.password = password;


this.email = email;


}


public Integer getId() {


return id;


}


public void setId(Integer id) {


this.id = id;


}


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;


}


public String getEmail() {


return email;


}


public

相关文章
|
3月前
|
SQL Java 数据库连接
Spring Data JPA 技术深度解析与应用指南
本文档全面介绍 Spring Data JPA 的核心概念、技术原理和实际应用。作为 Spring 生态系统中数据访问层的关键组件,Spring Data JPA 极大简化了 Java 持久层开发。本文将深入探讨其架构设计、核心接口、查询派生机制、事务管理以及与 Spring 框架的集成方式,并通过实际示例展示如何高效地使用这一技术。本文档约1500字,适合有一定 Spring 和 JPA 基础的开发者阅读。
392 0
|
4月前
|
前端开发 Java API
利用 Spring WebFlux 技术打造高效非阻塞 API 的完整开发方案与实践技巧
本文介绍了如何使用Spring WebFlux构建高效、可扩展的非阻塞API,涵盖响应式编程核心概念、技术方案设计及具体实现示例,适用于高并发场景下的API开发。
395 0
|
3月前
|
监控 安全 Java
Spring Cloud 微服务治理技术详解与实践指南
本文档全面介绍 Spring Cloud 微服务治理框架的核心组件、架构设计和实践应用。作为 Spring 生态系统中构建分布式系统的标准工具箱,Spring Cloud 提供了一套完整的微服务解决方案,涵盖服务发现、配置管理、负载均衡、熔断器等关键功能。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
234 1
|
3月前
|
监控 Kubernetes Cloud Native
Spring Batch 批处理框架技术详解与实践指南
本文档全面介绍 Spring Batch 批处理框架的核心架构、关键组件和实际应用场景。作为 Spring 生态系统中专门处理大规模数据批处理的框架,Spring Batch 为企业级批处理作业提供了可靠的解决方案。本文将深入探讨其作业流程、组件模型、错误处理机制、性能优化策略以及与现代云原生环境的集成方式,帮助开发者构建高效、稳定的批处理系统。
448 1
|
3月前
|
Java 数据库连接 开发者
Spring Framework 核心技术详解
本文档旨在深入解析 Java Spring Framework 的核心技术原理与应用。与侧重于快速开发的 Spring Boot 不同,本文将聚焦于 Spring 框架本身的设计理念、核心容器、控制反转(IoC)、面向切面编程(AOP)、数据访问与事务管理等基础且强大的模块。通过理解这些核心概念,开发者能够更深刻地领悟 Spring 生态系统的设计哲学,并具备解决复杂企业级应用开发问题的能力。
265 4
|
4月前
|
Java 应用服务中间件 开发者
Spring Boot 技术详解与应用实践
本文档旨在全面介绍 Spring Boot 这一广泛应用于现代企业级应用开发的框架。内容将涵盖 Spring Boot 的核心概念、核心特性、项目自动生成与结构解析、基础功能实现(如 RESTful API、数据访问)、配置管理以及最终的构建与部署。通过本文档,读者将能够理解 Spring Boot 如何简化 Spring 应用的初始搭建和开发过程,并掌握其基本使用方法。
363 2
|
3月前
|
监控 Java API
Spring WebFlux 响应式编程技术详解与实践指南
本文档全面介绍 Spring WebFlux 响应式编程框架的核心概念、架构设计和实际应用。作为 Spring 5 引入的革命性特性,WebFlux 提供了完全的响应式、非阻塞的 Web 开发栈,能够显著提升系统的并发处理能力和资源利用率。本文将深入探讨 Reactor 编程模型、响应式流规范、WebFlux 核心组件以及在实际项目中的最佳实践,帮助开发者构建高性能的响应式应用系统。
696 0
|
3月前
|
监控 Cloud Native Java
Spring Integration 企业集成模式技术详解与实践指南
本文档全面介绍 Spring Integration 框架的核心概念、架构设计和实际应用。作为 Spring 生态系统中的企业集成解决方案,Spring Integration 基于著名的 Enterprise Integration Patterns(EIP)提供了轻量级的消息驱动架构。本文将深入探讨其消息通道、端点、过滤器、转换器等核心组件,以及如何构建可靠的企业集成解决方案。
359 0
|
3月前
|
Kubernetes Java 微服务
Spring Cloud 微服务架构技术解析与实践指南
本文档全面介绍 Spring Cloud 微服务架构的核心组件、设计理念和实现方案。作为构建分布式系统的综合工具箱,Spring Cloud 为微服务架构提供了服务发现、配置管理、负载均衡、熔断器等关键功能的标准化实现。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
459 0
|
3月前
|
安全 Java 数据安全/隐私保护
Spring Security 核心技术解析与实践指南
本文档深入探讨 Spring Security 框架的核心架构、关键组件和实际应用。作为 Spring 生态系统中负责安全认证与授权的关键组件,Spring Security 为 Java 应用程序提供了全面的安全服务。本文将系统介绍其认证机制、授权模型、过滤器链原理、OAuth2 集成以及最佳实践,帮助开发者构建安全可靠的企业级应用。
228 0