文档章节

AOP

CarlDing
 CarlDing
发布于 2016/06/28 20:18
字数 896
阅读 47
收藏 5

 

AOP

spring的核心技术:

   IoC/DI - 一个概念 控制反转 - 依赖注入。

   AOP 面向切面的编程。

 

1:AOP简介

AOP的本质 - 就是一个超级强大,且容易配置,灵活干预的动态代理。

AOP观注的是项目中重复的代码.

 

 

2:AOP的一些概念

 

 

AOP决定做什么事 = 什么时间做      +     在哪儿做地点

切面             = 通知(前后环绕) +    切点哪一个类上哪一个方法上

Advisor           = Advice            +    Pointcut

不需要自己开发   = 要求自己开发     +    不求自己开发

 

 

Advice            

   前通知BeforeAdvice

   后通知AfterAdvice

            AfterThrowAdvice - 异常以后通知    

            AfterReturningAdvice - 正确执行成功以后通知

   环绕通知 MethodInterceptor 方法拦截

 

Pointcut切点

   JdkRegexpressionMethodPointcut - 基于正则表达式的说明

   AspectJExpressionPontcut

 

 

 

3:导入包

手工的项目:

 

maven:

  <dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-aspects</artifactId>

<version>4.3.0.RELEASE</version>

</dependency>

<dependency>

<groupId>aopalliance</groupId>

<artifactId>aopalliance</artifactId>

<version>1.0</version>

</dependency>

 

4:开发一个切面测试

@Test

public void test1(){

//1:声明被代理的目标对象

Person person = new Person();

//2:声明通知

Advice beforeAdvice = new MethodBeforeAdvice() {

@Override

public void before(Method method, Object[] args, Object target) throws Throwable {

System.err.println("在某个方法这前执行:"+method.getName());

}

};

//3:声明切点

AspectJExpressionPointcut cut =

new AspectJExpressionPointcut();

cut.setExpression("execution(* cn.spring..Person.say())");

//4:声明成切面

Advisor advisor = new DefaultPointcutAdvisor(cut,beforeAdvice);

//5:声明代理类

ProxyFactoryBean proxy = new ProxyFactoryBean();

//设置被代理的对象

proxy.setTarget(person);

//设置切面

proxy.addAdvisors(advisor);

//从里面获取到被代理的对象

Person pp = (Person) proxy.getObject();

pp.say();

}

 

 

 

5:更多通知的示例

添加一个后通知

   package cn.spring.demo03;

 

import java.lang.reflect.Method;

 

import org.aopalliance.aop.Advice;

import org.junit.Test;

import org.springframework.aop.Advisor;

import org.springframework.aop.AfterReturningAdvice;

import org.springframework.aop.BeforeAdvice;

import org.springframework.aop.MethodBeforeAdvice;

import org.springframework.aop.aspectj.AspectJExpressionPointcut;

import org.springframework.aop.framework.ProxyFactoryBean;

import org.springframework.aop.support.DefaultPointcutAdvisor;

 

public class Demo01_AOP {

@Test

public void test1(){

//1:声明被代理的目标对象

Person person = new Person();

//2:声明通知

Advice beforeAdvice = new MethodBeforeAdvice() {

@Override

public void before(Method method, Object[] args, Object target) throws Throwable {

System.err.println("在某个方法这前执行:"+method.getName());

}

};

 

//添加一个后通知

Advice afterAdvice = new AfterReturningAdvice() {

@Override

public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {

System.err.println("某个方法执行完成:"+method.getName());

}

};

 

 

//3:声明切点

AspectJExpressionPointcut cut =

new AspectJExpressionPointcut();

cut.setExpression("execution(* cn.spring..Person.say())");

//4:声明成切面

Advisor advisor = new DefaultPointcutAdvisor(cut,beforeAdvice);

Advisor advisor2 = new DefaultPointcutAdvisor(cut, afterAdvice);

Advisor advisor3 = new DefaultPointcutAdvisor(cut,new MyThrowAdvice());

//5:声明代理类

ProxyFactoryBean proxy = new ProxyFactoryBean();

//设置被代理的对象

proxy.setTarget(person);

//设置切面

proxy.addAdvisors(advisor,advisor2,advisor3);

//从里面获取到被代理的对象

Person pp = (Person) proxy.getObject();

pp.say();

}

}

 

 

6:将代码配置到spring的配置文件中实现切面

开发发一个环绕通知:

package cn.spring.demo03;

 

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

 

public class AroundAdvice implements MethodInterceptor {

@Override

public Object invoke(MethodInvocation invocation) throws Throwable {

System.err.println("方法拦截到了:" + invocation.getMethod().getName());

// 放行

Object returnValue = invocation.proceed();

System.err.println("拦截完成了..");

return returnValue;

}

 

}

 

 

配置:

<!-- 以下是切面 -->

<bean id="advice" class="cn.spring.demo03.AroundAdvice" />

<!-- 切点 -->

<bean id="cut"

class="org.springframework.aop.aspectj.AspectJExpressionPointcut">

<property name="expression" value="execution(* cn.spring..*.*(..))"></property>

</bean>

<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">

<property name="advice" ref="advice" />

<property name="pointcut" ref="cut"></property>

</bean>

 

<!-- 声明对Person的代理类 -->

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="target">

<bean class="cn.spring.demo03.Person"></bean>

</property>

<property name="interceptorNames">

<list>

<value>advisor</value>

</list>

</property>

 

测试:

 

 

上面的问题是:

   如果一个类想被代理,则必须要配置:

<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="target">

<bean class="cn.spring.demo03.Person"></bean>

</property>

<property name="interceptorNames">

<list>

<value>advisor</value>

</list>

</property>

 

7:自动代理的切面

自动的代理类,默认是后处理Bean的子类:

 

<!-- 配置自动代理的Bean -->

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />

 

使用aop命名空间:

 

 

<aop:auto-proxy/>

 

 

8:在项目中使用aop管理事务

使用模板:

   Platformtransactionmanager/datasourcetransactionmanager/hiberate...

   TransactionTremplate

 

 

 

<!-- 配置事务事务器 -->

<bean id="txm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSouce"></property>

</bean>

<!-- 配置事务的通知 -->

<tx:advice id="txAdvice" transaction-manager="txm">

<!-- 声明对哪些方法如何管理事务 -->

<tx:attributes>

<tx:method name="*" propagation="REQUIRED"/>

</tx:attributes>

</tx:advice>

<!-- 配置切面 -->

<aop:config>

<aop:pointcut expression="execution(* cn.ss..service.*Service.*(..))" id="cut"/>

<aop:advisor advice-ref="txAdvice" pointcut-ref="cut"/>

</aop:config>

 

 

 

 

 

 

 

 

 

 

 

© 著作权归作者所有

CarlDing
粉丝 5
博文 106
码字总数 78103
作品 0
济南
其他
私信 提问

暂无文章

实战项目-学成在线(一)

之前看的黑马程序员实战项目之一,打算以博客的形式写出来,也让自己重新温习一下。 1、项目背景 略(就是当前这东西很火,我们重点在开发,这些就略过) 2、功能模块 门户,学习中心,教学管...

lianbang_W
36分钟前
4
0
基于Vue的数字输入框组件开发

本文转载于:专业的前端网站➫基于Vue的数字输入框组件开发 1、概述 Vue组件开发的API:props、events和slots 2、组件代码 github地址:https://github.com/MengFangui/VueInputNumber 效果:...

前端老手
44分钟前
4
0
百度地图根据经纬度获取运动轨迹

<!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=n......

泉天下
46分钟前
5
0
学习记录(day04-axios增删改查、v-for循环、页面加载成功处理函数)

[TOC] 1.1 基本语法:插值表达式 <template> <div> {{username}} <br/> {{1+2+3}} <br/> {{'你的名字是:' + username}} <br/> {{'abc'.split('')}} </div><......

庭前云落
今天
5
0
CentOS Linux 7上将ISO映像文件写成可启动U盘

如今,电脑基本上都支持U盘启动,所以,可以将ISO文件写到U盘上,用来启动并安装操作系统。 我想将一个CentOS Linux 7的ISO映像文件写到U盘上,在CentOS Linux 7操作系统上,执行如下命令: ...

大别阿郎
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部