SSM-Spring教程(二)-AOP技术

SSM-Spring-AOP(二)、

1、Spring中Bean的的配置形式

①、通过xml方式配置bean

②、通过annotation(注解)方式配置bean

步骤:

①、在Spring的配置文件中配置自动扫描的包,告知IoC引擎去指定包以及子包下所有资源的注解

②、在相关bean中通过如下注解完成bean的创建以及属性的注入

@Value(“value”):为属性注入具体的值,可以放在变量上面,也可以放在setter风格的方法上面

@Component:创建对象,并纳入到IoC容器管理中。配置限定名为对象名的类纳入到IoC容器中(创建bean对象)

@Autowired:基于类型自动注入引用类型属性

@Repository:创建对象,并纳入到IoC容器管理中。限定名作为对象名 用于定义dao层的组件(IUserDao)

@Service:创建对象,并纳入到IoC容器管理中,限定名作为对象名 用于定义service组件(IUserSerivce)

@Controller:创建对象,并纳入到IoC容器管理中,限定名作为对象名 用于定义业务控制器(Serlvet)

@Scope(“prototype”):设置指定这个IoC对象的作用域 prototype|singleton

@Qualifier(“impl2”):将IoC容器中的impl2这个对象注入给当前对象属性

2、AOP技术:是面向切面(方面)编程

还记得代理模式中的安全性检查以及日志处理的问题吗?在某写操作执行之前需要做一些安全性检查,比如在删除信息之前需要确定当前账号是否登录过,甚至是哪怕登录过是否具有删除信息的权限呢?还有完成具体操作之后是否需要保存日志信息或者是完成一些资源释放等收尾工作。按照正常实现这些功能,可能会将安全性检查以及日志处理的代码充斥在业务逻辑中,这样并不好,所以Spring针对此类问题提供了AOP技术,对于业务方法来讲只需关注业务实现,而根本不需要关注安全、日志等非业务功能的实现

3、专业术语

①、切面 aspect @Aspect

RockSecurity|RockLogger,保存横切关注点方法的代码所在的类叫切面类

②、关注点Pointcut 关注掉表达式

是约定了那些方法切入通知 切入checkSecurity()|saveLogger()

③、通知 advice 即横切关注点表达式的方法

是横切关注点方法的代码所在的方法叫通知

④、连接点JoinPoint

连接点对象可以获取业务方法的相关参数,比如哪个方法?参数列表了等

4、通知的类型

①、前置通知 @Before

②、后置通知 @After

③、返回(返回值)通知 @AfterReturnning

④、异常通知 @AfterThrowing

⑤、环绕通知 @Around

5、开发步骤

①、定义切面

package com.rock.springaop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;


/**
 * FileName		:com.rock.springaop 	RockSecurity.java
 * TODO			:		
 * Copyright	:Copyright (c) 2015-2016 All Rights Reserved. Company: 01skill-soft.com Inc.
 * @author		:老张
 * @Date		:2018年11月9日:下午1:29:29
 * @version		:1.0
 * 
 *           Modification History: Date			Author 		Version 	Description
 *           ----------------------------------------------------------------------
 *           					   2018年11月9日 	老张	 		1.0 		1.0 Version
 */

@Aspect
@Component
public class RockSecurity {
	/**
	 * @TODO	 :是一个通知
	 * @Date	 :2018年11月9日 下午1:33:01
	 * @Author	 :老张   :
	 */
	@Before("execution (public int com.rock.springaop.MyMath.add(int,int))")
	public void checkSecurity(){
		System.out.println("RockSecurity.checkSecurity() is running........Before前置通知");
	}
}

②、定义通知

public void checkSecurity(){
    System.out.println("RockSecurity.checkSecurity() is running........Before前置通知");
}

③、定义关注点,约束哪些方法织入通知advice

@Before("execution (public int com.rock.springaop.MyMath.add(int,int))")

IMath.java

package com.rock.springaop;

/**FileName:	com.rock.aop 	IArithmeticCalculate.java
 * TODO:		
 * Copyright:	Copyright (c) 2015-2016 All Rights Reserved. Company: 01skill-soft.com Inc.
 * @author: 	老张
 * @Date:		2018年11月9日:上午9:54:42
 * @version: 	1.0
 * 
 *           Modification History: Date			Author 		Version 	Description
 *           ----------------------------------------------------------------------
 *           					   2018年11月9日 	老张	 		1.0 		1.0 Version
 * 
 */
public interface IArithmeticCalculate {
	/**
	 * @TODO	 :实现a+b的和
	 * @Date	 :2018年11月9日 上午9:55:05
	 * @Author	 :老张
	 * @param a
	 * @param b
	 * @return   :和值结果
	 */
	public int add(int a,int b);
	/**
	 * @TODO	 :计算a-b
	 * @Date	 :2018年11月9日 上午9:56:07
	 * @Author	 :老张
	 * @param a
	 * @param b
	 * @return   :a-b的结果
	 */
	public int sub(int a,int b);
	/**
	 * @TODO	 :a除以b
	 * @Date	 :2018年11月9日 上午9:56:34
	 * @Author	 :老张
	 * @param a
	 * @param b
	 * @return   :a除以b的结果
	 */
	public int div(int a,int b);
	/**
	 * @TODO	 :a乘以b
	 * @Date	 :2018年11月9日 上午9:57:31
	 * @Author	 :老张
	 * @param a
	 * @param b
	 * @return   :a乘以b的结果
	 */
	public int mul(int a,int b);
}

MyMath.java

import org.springframework.stereotype.Component;

/**FileName:	com.rock.aop 	MathProxy.java
 * TODO:		
 * Copyright:	Copyright (c) 2015-2016 All Rights Reserved. Company: 01skill-soft.com Inc.
 * @author: 	老张
 * @Date:		2018年11月9日:上午9:54:26
 * @version: 	1.0
 * 
 *           Modification History: Date			Author 		Version 	Description
 *           ----------------------------------------------------------------------
 *           					   2018年11月9日 	老张	 		1.0 		1.0 Version
 * 
 */
@Component(value="mymath")
public class IArithmeticCalculateImpl implements IArithmeticCalculate{
	@Override
	public int add(int a, int b) {
//		RockSecurity.检查();
		int c=a+b;
//		RockLogger.日志保存();
		return c;
	}

	@Override
	public int sub(int a, int b) {
//		RockSecurity.检查();
		int c=a-b;
//		RockLogger.日志保存();
		return c;
	}

	@Override
	public int div(int a, int b) {
//		RockSecurity.检查();
		int c=a/b;
//		RockLogger.日志保存();
		return c;
	}

	@Override
	public int mul(int a, int b) {
//		RockSecurity.检查();
		int c=a*b;
//		RockLogger.日志保存();
		return c;
	}
}

spring-aop.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 通知spring引擎解析这个包中的所有注解 -->
	<context:component-scan base-package="com.rock.springaop"></context:component-scan>
	<!-- 因为aop技术地层是通过代理模式实现的,这个告知spring引擎自动产生代理,即aop起作用 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

6、通知(Advice)类型

①、前置通知

@Aspect
@Component
public class RockSecurity {
	/**
	 * @TODO	 :是一个通知
	 * @Date	 :2018年11月9日 下午1:33:01
	 * @Author	 :老张   :
	 */
	@Before("execution (public int com.rock.springaop.MyMath.add(int,int))")
	public void checkSecurity(){
		System.out.println("RockSecurity.checkSecurity() is running........Before前置通知");
	}
}

②、后置通知@AfterReturning

	/**
	 * @TODO	 :周知通知,不管被织入方法是否抛出异常,都会执行通知
	 * @Date	 :2018年11月9日 下午4:22:53
	 * @Author	 :老张   :
	 */
	@After("execution (public int com.rock.springaop.MyMath.add(int,int))")
	public void saveLogger(){
		System.out.println("RockLogger.saveLogger() is running........After 后置通知");
	}

③、返回(返回值)通知

	/**
	 * @TODO	 :@AfterReturning  :返回(返回值)通知
	 * 			  @AfterReturning,注解中通过指定returning属性告知AOP将被织入的方法的返回值存于哪个变量
	 * 			    换言之,若你希望切面能够获取被织入的方法的返回值,必须使用返回通知
	 * 		        注意:前置通知和后置通知是获取不了方法的返回值的,它们只能获取到方法的方法名以及参数信息
	 * @Date	 :2018年11月9日 下午4:06:11
	 * @Author	 :老张
	 * @param result   :
	 */
	@AfterReturning(value="execution(* *.*(..))",returning="result")
	public void returnAdvice(Object result){
		System.out.println("RockOther.returnAdvice() is running.........."+result);
	}

④、异常通知@AfterThrowing

	/**
	 * @TODO	 :@AfterThrowing定义异常通知
	 * @Date	 :2018年11月9日 下午4:21:16
	 * @Author	 :老张
	 * @param ex1   :
	 */
	@AfterThrowing(value="execution (public int com.rock.springaop.MyMath.*(int,int))",throwing="ex1")
	public void textException(NullPointerException ex1){
		System.out.println("RockLogger.textException() is running........textException 后置通知=======");
		System.out.println(ex1);
	}

⑤、环绕通知

	/**
	 * @TODO	 :环绕通知   通过@Around 。环绕通知是功能最为强大的通知
	 * @Date	 :2018年11月9日 下午4:27:36
	 * @Author	 :老张
	 * @param jp   :
	 */
	@Around(value="execution (public int com.rock.springaop.MyMath.*(int,int))")
	public void textAround(JoinPoint jp){
		System.out.println("RockLogger.textAround() is running........");
		System.out.println("RockLogger.textAround()"+Arrays.asList(jp.getArgs()));
	}

5、一般问题总结

//1、切入点表达式的重用
//定义:在切面类中定义一个普通方法,在方法上方通过@Pointcut注解去约定这个方法是一个切入点方法。
//运用:在通知(方法)上方通过全类名.切入点方法名()方式访问
//注意:定义切入点方法的切面应该最先被处理,所以在这个切面中通过@Order(1)注解当前切面的优先级别最高
//2、在advice中怎样获取目标方法的相关数据(参数)
//使用:通过在通知(advice)方法中定义JoinPoint(连接点)获取对应的数据
//注意:别导错包了
//3、在advice方法中要获取目标方法的返回值需要通过返回值通知实现
//使用:@AfterReturning(value="",returning=“abcd”) returning:约定接收目标方法返回值的变量名
//public void testAfterReturnning(Object abcd)
//4、切入点表达式的写法 * …
/*
execution(* .(…))
execution(* com.rock.dao.UserDao.(…))
execution(
com.rock.dao..(…))
execution(* com.rock.dao.UserDao.set*(…)) //setUserid setPassword
*/

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值