【SSH】AOP

AOP简介

   AOP(AspectOriented Programming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善,是软件开发中的一个热点,也是Spring框架中的一个重要内容。AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

AOP基本概念

1、Aspect:对横切关注点模块化;

2、Advice:对横切性关注点的具体实现,包括调用目标之前执行(Before Advice)、调用目标之后执行(After Advice)、抛出异常(Throw Advice);

3、Pointcut:横切性关注点的应用范围,它定义了Advice应用到哪些JoinPoint上;应用范围,第一个* 表示所有的有无返回值,第二个*表示有无参数,代表匹配所有情况;

4、JoinPoint:连接点,调用目标方法的地方。在AOP中表示“在哪里做”;

5、Weave:织入,将Advice应用到TargetObject上的过程;

6、Introduction:引入,可以动态地为类添加方法,对类的增强叫做引入(Introduction),对方法的增强叫做织入(Weaving)。

【SSH】AOP_第1张图片

实现方式

   本Demo实现了在调用方法之前检查安全性。

一、注解方式(Annotation方式)

不变的代码:

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.spring;
/**
 * ClassName: UserManager
 * @Description: 接口
 * @author meng
 * @date 2016-5-6 上午10:51:44
 */
public interface UserManager {

	public void addUser(String username, String password);
	
	public void delUser(int userId);
}
</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.spring;
/**
 * ClassName: UserManagerImpl
 * @Description: 具体实现类
 * @author meng
 * @date 2016-5-6 上午10:51:24
 */
public class UserManagerImpl implements UserManager {

	public void addUser(String username, String password) {
		//checkSecurity();
		System.out.println("---------UserManagerImpl.add()--------");
	}

	public void delUser(int userId) {
		//checkSecurity();
		System.out.println("---------UserManagerImpl.delUser()--------");
	}
}
</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * ClassName: Client
 * @Description: 客户端
 * @author meng
 * @date 2016-5-6 上午10:52:05
 */
public class Client {
	public static void main(String[] args){
		//读取配置文件
		BeanFactory factory =new ClassPathXmlApplicationContext("applicationContext.xml");
		UserManager userManager=(UserManager)factory.getBean("userManager");
		userManager.addUser("张三", "123");
	}
}
</span>
重要部分:

1、  在横切类中添加注解

<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.jmj.spring;

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

//将横切性关注点模块化
//使用注解方式:Annotation
@Aspect
public class SecurityHandler {
	//定义检查安全性在调用添加方法之前
	
	/**
	 * 定义Advice,表示Advice应用到那些PointCut订阅的JoinPoint上
	 */
	//对横切性关注点的具体实现
	@Before("addAddMethod()")   //前置增强
	//@After("addAddMethod()")   //后置增强
	private void checkSecurity() {
		System.out.println("-------checkSecurity-------");
	}	
	
	/**
	 * 定义PointCut,PointCut的名称为addAddMethod(),此方法没有返回值和参数
	 * 该方法是一个标识,不进行调用
	 */
	//横切性关注点的应用范围
	//应用范围 ,第一个* 表示所有的有无返回值,第二个*表示有无参数,代表匹配所有情况
	@Pointcut("execution(* add*(..))")
	private void addAddMethod(){};

}
</span>

2、  在配置文件(applicationContext.xml)中,启用AspectJ对Annotation的支持

<span style="font-family:KaiTi_GB2312;font-size:18px;"><!--启用AspectJ对Annotation的支持  -->
          <aop:aspectj-autoproxy/>
          <bean id="userManager" class="com.jmj.spring.UserManagerImpl"/>
          <bean id="securityHandler" class="com.jmj.spring.SecurityHandler"/></span>

二、配置文件方式

   使用注解方式,只要需求有所变动,就需要修改横切类(SecurityHandler),且横切类中过于复杂。使用配置文件方式,可以为此类减压。

1、横切类

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class SecurityHandler {
	private void checkSecurity() {
		System.out.println("-------checkSecurity-------");
	}	
}</span>
   此类中,只需要切入方法的具体实现,而不需要管如何切入,何时切入?

2、在配置文件(applicationContext.xml)中,管理具体的切入形式

<span style="font-family:KaiTi_GB2312;font-size:18px;"> <bean id="userManager" class="com.jmj.spring.UserManagerImpl"/>
          <bean id="securityHandler" class="com.jmj.spring.SecurityHandler"/>
          
          <aop:config>
          <!--相当于注解中的aspect ,对横切关注点的模块化 -->
          	<aop:aspect id="securityAspect" ref="securityHandler">
          	
          		<!--定义了Advice应用到哪些JoinPoint上,对Spring来说是方法调用  -->
          		<!--以add开头的方法  -->
          		<!-- <aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/> -->
          		
          		<!--可以使用引用包,范围是:com.jmj.spring这个包下的所有类的所有方法  -->
          		<!-- <aop:pointcut id="addAddMethod" expression="execution(* com.jmj.spring.*.*(..))"/> -->
          		
          		<!--只对添加和删除起作用,对以add和del开头的方法起作用  -->
          		<aop:pointcut id="addAddMethod" expression="execution(* com.jmj.spring.*.add*(..)) || execution(* com.jmj.spring.*.del*(..))"/>
          		
          		<!--对横切关注点的具体实现  -->
          		<aop:before method="checkSecurity" pointcut-ref="addAddMethod"/>
          		<!-- <aop:after method="checkSecurity" pointcut-ref="addAddMethod"/> -->
          	</aop:aspect>
          </aop:config></span>

总结

AOP和OOP的关系,如图所示:

【SSH】AOP_第2张图片

   AOP的优点:低耦合,高扩展。

你可能感兴趣的:(ssh)