Spring AOP应用实例demo

简介:

AOPAspect-Oriented Programming。面向方面编程)。能够说是OOPObject-OrientedPrograming。面向对象编程)的补充和完好。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。


OOP的问题,AOP的补充


当我们须要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP同意你定义从上到下的关系,但并不适合定义从左到右的关系。

比如日志功能。日志代码往往水平地散布在全部对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其它类型的代码,如安全性、异常处理和透明的持续性也是如此。这样的散布在各处的无关的代码被称为横切(cross-cutting)代码。在OOP设计中,它导致了大量代码的反复,而不利于各个模块的重用。

 

所谓“方面”,简单地说,就是将那些与业务无关。却为业务模块所共同调用的逻辑或责任封装起来。便于降低系统的反复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

 

Spring中对 AOP的支持

 

Spring AOP代理由Spring IoC容器负责生成、管理,其依赖关系也由 IoC容器负责管理。因此,AOP代理能够直接使用容器中的其它Bean实例作为目标,这样的关系可由 IoC容器的依赖注入提供。Spring默认使用 Java动态代理来创建AOP代理。这样就能够为不论什么接口实例创建代理了。当须要代理的类不是代理接口的时候, Spring自己主动会切换为使用 CGLIB代理,也可强制使用 CGLIB


程序猿參与部分 


AOP编程事实上是非常easy的事情。

纵观 AOP编程,当中须要程序猿參与的仅仅有三个部分:

 

   定义普通业务组件。

   定义切入点,一个切入点可能横切多个业务组件。

   定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作。

 

所以进行 AOP编程的关键就是定义切入点和定义增强处理。一旦定义了合适的切入点和增强处理,AOP框架将会自己主动生成AOP代理。即:代理对象的方法 =增强处理 +被代理对象的方法。

 

Spring中使用方式:

 

基于 Annotation的“零配置”方式。

 

1)启动注解。配置文件applicationContext.xml

<!-- 启动对@AspectJ注解的支持 -->     
<aop:aspectj-autoproxy/>

<bean id="user" class="com.tgb.spring.aop.IUserImpl"/>

<bean id="check" class="com.tgb.spring.aop.CheckUser"/>

2)编写切面类

package com.tgb.spring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect 
public class CheckUser {

	@Pointcut("execution(* com.tgb.spring.aop.*.find*(..))")
	public void checkUser(){
		System.out.println("**************The System is Searching Information For You****************");
	}
	
	@Pointcut("execution(* com.tgb.spring.aop.*.add*(..))")
	public void checkAdd(){
		System.out.println("**************<< Add User >> Checking.....***************");
	}
	
	@Before("checkUser()")
	public void beforeCheck(){
		System.out.println(">>>>>>>> 准备搜查用户..........");
	}
	
	@After("checkUser()")
	public void afterCheck(){
		System.out.println(">>>>>>>> 搜查用户完成..........");
	}

	@Before("checkAdd()")
	public void beforeAdd(){
		System.out.println(">>>>>>>> 添加用户--检查ing..........");
	}
	
	@After("checkAdd()")
	public void afterAdd(){
		System.out.println(">>>>>>>> 添加用户--检查完成!

未发现异常!.........."); } //声明围绕通知 @Around("checkUser()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入方法---围绕通知"); Object o = pjp.proceed(); System.out.println("退出方法---围绕通知"); return o; } }

3)定义接口

package com.tgb.spring.aop;

public interface IUser {

	public String findUser(String username);
	public void addUser(String username);
	public void findAll();
}

4)定义实现

package com.tgb.spring.aop;

import java.util.HashMap;
import java.util.Map;

public class IUserImpl implements IUser {

	public static Map map = null;
	public static void init(){
		String[] list = {"Lucy", "Tom", "小明", "Smith", "Hello"};
		Map tmp = new HashMap();
		for(int i=0; i<list.length; i++){
			tmp.put(list[i], list[i]+"00");
		}
		map = tmp;
	}
	public void addUser(String username) {
		init();
		map.put(username, username+"11");
		System.out.println("--------------【addUser】: "+username+" --------------");
		System.out.println("【The new List:"+map+"】");
	}

	public void findAll() {
		init();
		System.out.println("---------------【findAll】: "+map+" ------------------");
	}

	public String findUser(String username) {
		init();
		String password = "没查到该用户";
		if(map.containsKey(username)){
			password = map.get(username).toString();
		}
		System.out.println("-----------------【findUser】-----------------");
		System.out.println("-----------------Username:"+username+"-----------------");
		System.out.println("-----------------【Result】:"+password+"------------------");
		return password;
		
	}

}

5)測试

public class Test {
	
	public static void main(String as[]){
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		IUser user = (IUser) factory.getBean("user");
		user.findAll();
		
		User u = new User();
//		u.setUsername("Tom");
//		user.findUser(u.getUsername());
		
		/*u.setUsername("haha");
		user.addUser(u.getUsername());*/
	}
}

运行结果:

 

进入方法---围绕通知

>>>>>>>>准备搜查用户..........

---------------【findAll】: {Smith=Smith00, Tom=Tom00, 小明=小明00, Lucy=Lucy00,Hello=Hello00} ------------------

退出方法---围绕通知

>>>>>>>> 搜查用户完成..........

 

注:@Before是在所拦截方法运行之前运行一段逻辑。@After是在所拦截方法运行之后运行一段逻辑。@Around是能够同一时候在所拦截方法的前后运行一段逻辑。

 

以上是针对注解的方式来实现。那么配置文件也一样,仅仅须要在applicationContext.xml中加入例如以下代码:

<!--  <aop:config>
		<aop:pointcut id="find" expression="execution(* com.tgb.spring.aop.*.find*(..))" />
		<aop:pointcut id="add" 	expression="execution(* com.tgb.spring.aop.*.add*(..))" />
		
		<aop:aspect id="checkUser" ref="check">
			<aop:before method="beforeCheck" pointcut-ref="find"/>
			<aop:after method="afterCheck" pointcut-ref="find"/>
		</aop:aspect>
		
		<aop:aspect id="checkAdd" ref="check">
			<aop:before method="beforeAdd" pointcut-ref="add"/>
			<aop:after method="afterAdd" pointcut-ref="add"/>
		</aop:aspect>
	
	</aop:config>-->

总结:

 

以上是简介了一下怎样使用Spring AOP,在使用的过程中也加深我们对AOP思想的理解。事实上AOP就是要我们实现热插拔效果,下篇会继续介绍Spring AOP的实现原理。

 

附:在使用过程中注意JDK版本号与易用的aspectJrt的版本号问题








本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5246595.html,如需转载请自行联系原作者
相关文章
|
11月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1484 3
|
10月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
854 0
|
10月前
|
SQL Java 数据库连接
Spring Data JPA 技术深度解析与应用指南
本文档全面介绍 Spring Data JPA 的核心概念、技术原理和实际应用。作为 Spring 生态系统中数据访问层的关键组件,Spring Data JPA 极大简化了 Java 持久层开发。本文将深入探讨其架构设计、核心接口、查询派生机制、事务管理以及与 Spring 框架的集成方式,并通过实际示例展示如何高效地使用这一技术。本文档约1500字,适合有一定 Spring 和 JPA 基础的开发者阅读。
903 0
|
9月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
9月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
790 8
|
11月前
|
Java 应用服务中间件 开发者
Spring Boot 技术详解与应用实践
本文档旨在全面介绍 Spring Boot 这一广泛应用于现代企业级应用开发的框架。内容将涵盖 Spring Boot 的核心概念、核心特性、项目自动生成与结构解析、基础功能实现(如 RESTful API、数据访问)、配置管理以及最终的构建与部署。通过本文档,读者将能够理解 Spring Boot 如何简化 Spring 应用的初始搭建和开发过程,并掌握其基本使用方法。
755 2
|
11月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
11月前
|
安全 算法 Java
在Spring Boot中应用Jasypt以加密配置信息。
通过以上步骤,可以在Spring Boot应用中有效地利用Jasypt对配置信息进行加密,这样即使配置文件被泄露,其中的敏感信息也不会直接暴露给攻击者。这是一种在不牺牲操作复杂度的情况下提升应用安全性的简便方法。
1569 10
|
12月前
|
安全 Java Nacos
0代码改动实现Spring应用数据库帐密自动轮转
Nacos作为国内被广泛使用的配置中心,已经成为应用侧的基础设施产品,近年来安全问题被更多关注,这是中国国内软件行业逐渐迈向成熟的标志,也是必经之路,Nacos提供配置加密存储-运行时轮转的核心安全能力,将在应用安全领域承担更多职责。