1.代理模式

找个人将你原本想做的事情给做了。

三个部分组成:

抽象主题角色:真实主题和代理主题的共同接口。

真实主题角色:定义了代理角色所代表的真实对象。

代理主题角色:含有对真实主题角色的引用。代理角色通常在将客户端调用传递给真实主题对象之前或者之后执行某些操作。

以收快递的案例:

收快递并签字,这个是抽象主题。

买家,货物的主人,这个是真实主题。

门卫代理收货并签字,这个是代理主题。

代理模式的类图:

实现步骤:

1).定义一个抽象的主题。

package com.jinglin.staticproxy;
/**
* 定义一个抽象的主题,这个主题就规定了方法
* @author sony
*
*/
public interface IGetSomething {
void getsomething();
}

2)实现的是真实主题的类,这个类继承自抽象主题:

public class RealGetSomething implements IGetSomething {
@Override
public void getsomething() {
// TODO Auto-generated method stub
System.out.println("主人亲自收货并签字了");
}
}

3)实现的是代理主题的类,这个类继承自抽象主题,但是这个类关联了所代理的主题对象。

package com.jinglin.staticproxy;

/**
* 这是一个代理主题,也需要继承自抽象主题
* @author sony
*
*/
public class ProxyGetSomething implements IGetSomething { private RealGetSomething realGetSomething;//依赖关系 public RealGetSomething getRealGetSomething() {
return realGetSomething;
} public void setRealGetSomething(RealGetSomething realGetSomething) {
this.realGetSomething = realGetSomething;
}
public ProxyGetSomething(RealGetSomething _realGetSomething){
this.realGetSomething=_realGetSomething;
} @Override
public void getsomething() {
// TODO Auto-generated method stub
getbefore();
realGetSomething.getsomething();
getafter();
} private void getbefore(){
System.out.println("检查快递是否是本小区的");
}
private void getafter(){
System.out.println("快递签收完毕");
} }

4)编写客户端调用的类(对外部开放的):

package com.jinglin.staticproxy;

public class ClientDemo {
private IGetSomething igetsomething; public IGetSomething getIgetsomething() {
return igetsomething;
} public void setIgetsomething(IGetSomething igetsomething) {
this.igetsomething = igetsomething;
}
public ClientDemo(IGetSomething _igetsomething){
this.igetsomething=_igetsomething;
}
public void show(){
igetsomething.getsomething();
}
}

5)最后编写测试类:

package com.jinglin.test;

import org.junit.Test;

import com.jinglin.staticproxy.ClientDemo;
import com.jinglin.staticproxy.IGetSomething;
import com.jinglin.staticproxy.ProxyGetSomething;
import com.jinglin.staticproxy.RealGetSomething; public class ProxyStaticTest {
@Test
public void testit(){
RealGetSomething realGetSomething = new RealGetSomething();
IGetSomething igetsomething = new ProxyGetSomething(realGetSomething);
ClientDemo client = new ClientDemo(igetsomething);
client.show();
}
}

2.分析刚才所实现的代理模式的问题

1)实现一个代理,必然要定义一个接口,要实现这个接口。如果一旦代理的内容很多,那么实现的接口就会很多。

2)代理平台,这个代理平台就帮我们实现根据传入的对象来实现代理。

动态代理,模拟mybatis的动态代理

a.首先定义了一个所有数据操作的接口层:

package com.jinglin.mybatis;
/**
* 定义一个接口,这个接口就规定了对数据库的操作
* @author sony
*
*/
public interface ICommandData {
void opdata();
}

b.定义一个继承自这个接口的真实主题对象:

public class DeleteData implements ICommandData {

    @Override
public void opdata() {
// TODO Auto-generated method stub
System.out.println("这是对于数据库的删除方法");
}
}

另外一个:

public class SelectData implements ICommandData{
@Override
public void opdata() {
// TODO Auto-generated method stub
System.out.println("这是对于数据库的查询的方法");
}
}

c.定义一个动态代理的平台:模拟了一个getMapper方法:

package com.jinglin.mybatis;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class MybatisMapperHandler implements InvocationHandler { private Object obj;
public void getconnection(){
System.out.println("获取连接对象,获取执行命令对象");
}
public void closeconnection(){
System.out.println("执行完毕,关闭连接对象");
}
public Object getMapper(Class<?> classz) throws InstantiationException, IllegalAccessException {
obj = classz.newInstance();
return Proxy.newProxyInstance(classz.getClassLoader(),
classz.getInterfaces(),
this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
getconnection();
Object ret = method.invoke(obj, args);
closeconnection();
return ret;
}
}

最后在测试的时候调用:

public class TestIt {
@Test
public void testit() throws InstantiationException, IllegalAccessException{
MybatisMapperHandler mybatisMapperHandler = new MybatisMapperHandler();
ICommandData icommandData = new SelectData();
ICommandData selectdatamapper=(ICommandData) mybatisMapperHandler.getMapper(icommandData.getClass());
selectdatamapper.opdata(); ICommandData icommandData2 = new DeleteData();
icommandData2 = (ICommandData) mybatisMapperHandler.getMapper(icommandData2.getClass());
icommandData2.opdata();
}
}

4.AOP编程

1)程序代码的构成部分?

通用代码+业务代码

2)开发一个销售记录和进货的功能,每次销售和每次进货都要有日志记录。

业务代码和通用代码的分离的思想,AOP思想,在实际开发的时候将通用代码植入到所需的业务代码中。AOP减少模块间的耦合,低侵入

3)AOP的开发,可以借助于Spring。

 

Aspect(切面):

将散落于各个业务逻辑之中的Cross-cutting concerns收集起来,设计成各个独立可重用的对象,这些对象称为Aspect

例:动态代理中的LogHandler就是一个Aspect

Advice(增强):在特定的连接点上执行的动作,执行的这个动作就相当于对原始对象的功能做了增强。

Aspect对Cross-cutting concerns(横切关注点)的具体实现称为Advice。

Advice中包括了Cross-cutting concerns的行为或所要提供的服务

例:在动态代理的示例中代理类的invoke()就是Advice的具体实例

Joinpoint(连接点):

Advice在应用程序执行时加入业务流程的点或时机称为Joinpoint,具体来说就是Advice在应用程序中被执行的时机

Spring只支持方法的Joinpoint,执行时机可能是某个方法被执行之前或之后

Pointcut(切入点):切入点就是一系列连接点的集合。

Pointcut定义了感兴趣的Joinpoint,当调用的方法符合Pointcut表示式时,将Advice织入应用程序上提供服务

在Spring中,您可以在定义文件或Annotation中编写Pointcut,说明哪些Advice要应用至方法的前后

Target(目标对象):真正执行业务逻辑的对象

一个Advice被应用的对象或目标对象,也就是被代理的类

例:在动态代理的示例中HelloSpeaker就是LogHandler中Advice的Target

Weave(织入):将切面整合到程序的执行流程中

Advice被应用至对象之上的过程称为织入,在AOP中织入的方式有几个时间点:

编译时期

类加载时期

执行时期

案例:

开发一个商业信息管理系统,这个商业信息管理系统主要的功能就是销售,就是进货。通用功能就是日志记录,权限检查,事务处理等。

1)开发业务类或者通用代码的类。

注意,类与类之间无任何关联。

2)将开发的类加入到spring中,作为bean。

首先修改beans的声明

<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- 将bean对象加入到容器中 -->
<!-- 配置业务类的bean-->
<bean id="purchaseservice" class="com.jinglin.aop.service.PurchaseService"></bean>
<bean id="sellservice" class="com.jinglin.aop.service.SellService"></bean>
<!-- 配置切面类的 -->
<bean id="logcommon" class="com.jinglin.aop.common.LogCommon"></bean>
<bean id="rolecommon" class="com.jinglin.aop.common.RoleCommon"></bean>

3)配置AOP的切面:

<!--对于AOP的配置  -->
<aop:config>
<!-- 配置程序执行前的切面类 -->
<aop:aspect id="roleaspect" ref="rolecommon">
<!-- 配置连接点的集合 -->
<aop:pointcut expression="execution(* com..*.*Service.*(..))" id="mypointcut"/>
<!--业务方法执行之前的配置增强 -->
<aop:before method="beforeexecution" pointcut-ref="mypointcut"/>
</aop:aspect>
<!-- 配置程序执行后的切面类 -->
<aop:aspect id="logaspect" ref="logcommon">
<!-- 配置连接点的集合 -->
<aop:pointcut expression="execution(* com..*.*Service.*(..))" id="mypointcut2"/>
<!--业务方法执行之后的配置增强 -->
<aop:after method="afterexecution" pointcut-ref="mypointcut2"/>
</aop:aspect>
</aop:config>

4)编写测试类:

public class AopTest {
static ClassPathXmlApplicationContext ac=null;
static{
ac=new ClassPathXmlApplicationContext("applicationContext.xml");
}
@Test
public void aoptest(){
//进货
PurchaseService purchaseService=(PurchaseService) ac.getBean("purchaseservice");
purchaseService.stockit(); //销售
SellService sellService=(SellService) ac.getBean("sellservice");
sellService.sellit();
}
}

Spring中的AOP开发的更多相关文章

  1. Spring中的AOP

    什么是AOP? (以下内容来自百度百科) 面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种 ...

  2. Spring中的AOP 专题

    Caused by: java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advi ...

  3. Spring学习笔记(四)—— Spring中的AOP

    一.AOP概述 AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善.O ...

  4. 2018.12.24 Spring中的aop演示(也就是运用aop技术实现代理模式)

    Aop的最大意义是:在不改变原来代码的前提下,也不对源代码做任何协议接口要求.而实现了类似插件的方式,来修改源代码,给源代码插入新的执行代码. 1.spring中的aop演示 aop:面向方面编程.不 ...

  5. (五)Spring 中的 aop

    目录 文章目录 AOP概念 AOP原理 AOP术语 **`Spring`** 中的 **`aop`** 的操作 使用 `AspectJ` 实现 `aop` 的两种方式 AOP概念 浅理解 aop :面 ...

  6. Spring中关于AOP的实践之概念

    一.什么是AOP AOP:也称作面向切面编程 在分享几个概念执行我想先举个栗子(可能例子举得并不是特别恰当): 1.假如路人A走在大街上,被一群坏人绑架了: 2.警察叔叔接到报警迅速展开行动:收集情报 ...

  7. spring中的AOP 以及各种通知 配置

    理解了前面动态代理对象的原理之后,其实还是有很多不足之处,因为如果在项目中有20多个类,每个类有100多个方法都需要判断是不是要开事务,那么方法调用那里会相当麻烦. spring中的AOP很好地解决了 ...

  8. JavaWeb_(Spring框架)认识Spring中的aop

    1.aop思想介绍(面向切面编程):将纵向重复代码,横向抽取解决,简称:横切 2.Spring中的aop:无需我们自己写动态代理的代码,spring可以将容器中管理对象生成动态代理对象,前提是我们对他 ...

  9. Spring 中基于 AOP 的 @AspectJ

    Spring 中基于 AOP 的 @AspectJ @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格. 通过在你的基于架构的 XML ...

随机推荐

  1. 在Linux下安装Oracle12c

    其实,对于oracle数据库和oracle实例的安装,借用图形化安装还是比较容易的,只是有个别地方需要特别注意外,其余的默认安装即可: 1.安装前的准备: 启动SSH工具: 先启动倒数第三个(想用图像 ...

  2. hadoop全分布式环境搭建

    本文主要介绍基本的hadoop的搭建过程.首先说下我的环境准备.我的笔记本使用的是Windows10专业版,装的虚拟机软件为VMware WorkStation Pro,虚拟机使用的系统为centos ...

  3. python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性

    先介绍几个类中的应用__getattr__,__setattr__,__get__,__set__,__getattribute__,. __getattr__:当在类中找不到attribute的时候 ...

  4. 华为OJ之自动售货系统

    本题主要难点有两部分: 1,找零算法.如何找零应该是最具技巧性的部分,根据已有的硬币金额分布,对应的解决办法可能会有不同.本题中的1,2,5,10这种情况满足贪心性质,故我们简单的用贪心算法的思想来解 ...

  5. 本地存储之cookie、localStorage、sessionStorage

    一.本地存储分为cookie,以及新增的localStorage和sessionStorage 1.cookie存储在本地,容量最大4k,在同源的http请求时携带传递,损耗带宽,可设置访问路径,只有 ...

  6. Selenium自动化初级/中级网络授课班招生

    近期学习selenium和appium的测试人员越来越多,应广大刚接触UI自动化以及对selenium想要更深入了解的测试人员的要求,特请一位资深测试架构师为我们开课讲解selenium,以及如何设计 ...

  7. Spring Data JPA在Spring Boot中的应用

    1.JPA JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.他的出现主要是为了简 ...

  8. Mybitis配置文件中的别名以及mapper中的namespace

    1 基本知识 MyBatis中如果每次配置类名都要写全称也太不友好了,我们可以通过在主配置文件中配置别名,就不再需要指定完整的包名了. 别名的基本用法: <configuration> & ...

  9. (转)volatile关键字

    Java线程:volatile关键字   Java™ 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量 ...

  10. java笔录---反射机制(1)

    引言   为了方便记忆java的反射机制,在这里仔细的总结了一下.主要是怕以后忘记了,这样也方便回忆.因为最近利用空余时间深入的了解spring和Mybatis框架,   像spring中核心模块IO ...