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. CSS预编译与PostCSS以及Webpack构建CSS综合方案

    CSS全称Cascading Style Sheets(层叠样式表),用来为HTML添加样式,本质上是一种标记类语言.CSS前期发展非常迅速,1994年哈肯·维姆·莱首次提出CSS,1996年12月W ...

  2. Invert a binary tree 翻转一棵二叉树

    Invert a binary tree 翻转一棵二叉树 假设有如下一棵二叉树: 4  / \   2    7  / \   / \ 1  3 6  9翻转后: 4     /    \    7 ...

  3. 微信小程序怎么用?线下商家最适合玩小程序

    随着微信小程序不断地释放新功能,许多行业越来越关注小程序,目前已经有不少餐饮和线下传统零售企业开始谋划利用好小程序.但是,线下商业有着复杂的场景,如何针对自己行业的特点和需求开发出属于自己的小程序,是 ...

  4. C# 创建、部署和调用WebService的简单示例

    废话不多说,下面开始创建一个简单的webservice的例子.这里我用的是Visual Studio 2015开发工具. 首先创建一个空的Web应用程序. 然后鼠标右键点击项目,选择 添加>新建 ...

  5. MyBatis+mysql 简单分页

    注意:limit不能跟动态内容 <select id="fenYe" parameterType="int" resultType="com.x ...

  6. 第一回:Scrapy的试水

    前言:今天算是见到Scrapy的第二天,之前只是偶尔查了查,对于这个框架的各种解释,我-----都-----看------不------懂----,没办法,见面就是刚. 目的:如题,试水 目标:< ...

  7. HTTP学习

    HTTP(HyperText Transfer Protocol)全称"超文本传输协议" HTTP是基于 TCP/IP 协议的应用层协议 现在日常使用版本 HTTP/1.1 一个H ...

  8. C#导入导出Excele数据

    注:对于实体类对象最好新建一个并且继承原有实体类,这样可以将类型进行修改: 方法一:此种方法是用EPPLUS中的FileInfo流进行读取的(是不是流我还真不太了解,若有懂得请留言,非常感谢了) us ...

  9. PHP执行linux命令mkdir权限问题

    在linux系统中,root帐号执行php命令: mkdir('test', 0777); 结果文件的权限依然为: drwxr-xr-x 2 root root   Jul 27 19:30 test ...

  10. 47. leetcode 437. Path Sum III

    437. Path Sum III You are given a binary tree in which each node contains an integer value. Find the ...