回顾SpringAOP的实现原理

SpringAOP中@EnableAspectJAutoProxy注解的作用 理解@EnableAspectJAutoProxy注解的作用 阅读详情

一 概述

面向切面编程的织入时机

1. 编译期织入(AspectJ)

2. 类加载加载织入(AspectJ 5+)

3. 运行时(Spring AOP)

二 运行时织入的实现逻辑

代理对象的交互图

如图,客户端是通过代理对象间接的同目标对象进行交互,换言之,目标对象委托了代理对象同客户端进行交互。

根据类图可知,客户端通过接口来对目标对象或代理对象进行引用,这里就涉及了一个很重要的原则,面向接口编程,这时候就涉及到两个重要的结论:

1. 因为客户端调用的真正对象的方法,代理类都要有。所以代理对象和调用对象都要作为该接口的实现类。

2. 代理对象会将方法委托给真正的对象进行执行,而代理类就执行一些额外的逻辑,即AOP织入的逻辑。

运行时织入是通过代理对象,代理可以分为了两种:静态代理和动态代理。

其中动态代理又分为基于接口代理和基于继承代理实现,这两类的代表为JDK代理与CGlib代理。

三 运行时织入之静态代理的实现

接口类

public interface IA {

    void getName();
}

接口实际实现类

public class RealIA implements IA{

    @Override
    public void getName() {
        System.out.println("真正对象实现请求!");
    }
}

接口代理类

public class ProxyIA implements IA{

    //代理对象需要委托真正对象去完成一些逻辑
    private RealIA realIA;

    //强制
    public ProxyIA(RealIA realIA) {
        this.realIA = realIA;
    }

    //代理对象不会实现真是的逻辑
    @Override
    public void getName() {

        //类似于AOP的before,after,around
        //代理对象完成其他逻辑
        System.out.println("before代理逻辑");

        //代理对象委托真正的对象来完成客户端逻辑
        try {
            realIA.getName();
        } catch (Exception e) {
            System.out.println("ex:" + e.getMessage());
            throw e;
        } finally {
            System.out.println("after代理逻辑");
        }
    }
}

由上述静态代理的实现可知,当接口中方法越多,需要实现的代理方法越多时,重复的逻辑就越多。

四 运行时织入之JDK动态代理

1. JDK代理需要通过java.lang.reflect.Proxy类来动态生成代理类

2. 代理类需要实现织入逻辑需要实现接口InvocationHandler

3. JDK动态代理只能基于接口进行动态代理

JDK动态代理代码实现

JDK动态代理类

public class JdkProxySubject implements InvocationHandler {

    private RealIA realIA;

    public JdkProxySubject(RealIA realIA) {
        this.realIA = realIA;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //织入的逻辑
        System.out.println("before代理");

        Object result = null;
        try{
            //通过invoke方法执行动态代理的逻辑
            //Method通过应用反射机制,来动态反射方法
            result = method.invoke(realIA,args);
        }catch (Exception e){

        }finally {
            //织入的逻辑
            System.out.println("after代理");
        }
        return result;
    }
}

JDK动态代理客户端

public class JdkClient {

    public static void main(String[] args) {
        IA ia = (IA) Proxy.newProxyInstance(JdkClient.class.getClassLoader(),
                new Class[]{IA.class},new JdkProxySubject(new RealIA()));
        ia.getName();
    }
}

结合上面的IA接口和RealIA实现类,就完成了JDK动态代理的实例。

五 运行时织入之JDK动态代理底层逻辑

根据实例代码可知JDK动态代理的代码生成,先通过Proxy.newProxyInstance方法,接着调用一次通过方法getProxyClass0,ProxyClassFactory,ProxyGenerator方法实现动态代理的代码的生成 ,这个过程生成的代码时字节码,最后通过Java的反射机制new出实例代码。

newProxyInstance方法源码

 @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

        //寻找或者生成指定代理类
        /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);
}

getProxyClass0方法源码

    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        //如果缓存中存在代码,则getProxyClass0方法先从缓存中获取代码,如果没有就会通过ProxyClassFactory进行创建并放入缓存
        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
        return proxyClassCache.get(loader, interfaces);
    }

缓存源码

 proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

ProxyClassFactory方法源码

    private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // prefix for all proxy class names
        private static final String proxyClassNamePrefix = "$Proxy";

        // next number to use for generation of unique proxy class names
        private static final AtomicLong nextUniqueNumber = new AtomicLong();

        @Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
            for (Class<?> intf : interfaces) {

                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                //接口的类 
                Class<?> interfaceClass = null;
                try {
                    //找到接口类
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
}

代理类名称格式

   /*
    * Choose a name for the proxy class to generate.
    */
    long num = nextUniqueNumber.getAndIncrement();
    String proxyName = proxyPkg + proxyClassNamePrefix + num;

根据源码可知,代理类的最后名称中包含long类型的数字字符。

六 运行时织入之CGlib动态代理

Cglib动态代理类

public class IAInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("before in cglib");
            Object result = null;
            try{
                result = methodProxy.invokeSuper(o,objects);
            }catch (Exception e){
                System.out.println(e.getMessage());
            }finally {
                System.out.println("after in cglib");
            }
            return result;
    }
}

Cglib动态代理客户端类

public class CglibClient {

    public static void main(String[] args) {
        //Cglib的增强对象
        Enhancer enhancer = new Enhancer();
        //设置增强类型,增强真是对象
        enhancer.setSuperclass(RealIA.class);
        enhancer.setCallback(new IAInterceptor());
        IA ia = (IA) enhancer.create();
        ia.getName();
    }
}

基于静态代理的接口IA真正实现类RealIA来实现的代码实例 。

七 JDK动态代理和Cglib动态代理之间的区别

1. JDK动态代理时基于接口实现的动态代理,对接口中的方法进行代理织入代码。

2. Cglib动态代理是基于继承实现的动态代理,所以实现Static和final类进行代理。

3. 同因为Cglib动态代理是基于继承实现的动态代理,所以无法完成Static和private方法的代理。

4. 因为接口中方法不可以是private方法,所以JDK动态代理也无法完成private方法的代理。

八 Spring创建代理bean的方法

对于动态代理而言,同时存在JDK动态代理和Cglib动态代理两种。

根据Spring创建代理类的时序图可得,先由AbstractAutoProxyCreator类调用createProxy方法返回代理类。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {	
    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		return proxyFactory.getProxy(getProxyClassLoader());
	}
}

而createProxy方法又是调用ProxyFactory来生成的,然而createProxy方法又是委托给ProxyCreatorSupport类来生成。

public class ProxyCreatorSupport extends AdvisedSupport {
    protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}
}

最后ProxyCreatorSupport又是通过DefaultAopProxyFactory来实现的。

public class ProxyCreatorSupport extends AdvisedSupport {
    public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}
}

DefaultAopProxyFactory实现createAopProxy生成代理类的方法。

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

	/**
	 * Whether this environment lives within a native image.
	 * Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
	 * @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
	 */
	private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);

	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (!IN_NATIVE_IMAGE &&
				(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
            //使用JDK动态代理
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
            //Cglib动态代理
			return new ObjenesisCglibAopProxy(config);
		}
		else {
            //使用JDK动态代理
			return new JdkDynamicAopProxy(config);
		}
	}
}

根据源码可知,Spring中只有两种情况使用JDK动态代理,其他的情况都是使用Cglib动态代理。

根据上述源码可知,当目标对象实现了接口的情况下,默认使用的JDK动态代理,而没有实现接口的情况下,则使用的是Cglib动态代理,当然在目标对象实现了接口的情况下,但是强制使用Cglib动态代理的情况下,还是会通过Cglib动态代理。

九 SpringBoot中强制使用CGlib动态代理的方法

@SpringBootApplication
//强制使用Cglib动态代理
public class SpringaopApplication {

    public static void main(String[] args) { SpringApplication.run(SpringaopApplication.class, args); }
}

根据实例代码可知通过注解@EnableAspectJAutoProxy(proxyTargetClass = true)可以强制使用Cglib动态代理。

这样做的原理的使得if (!IN_NATIVE_IMAGE && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)))判断条件中的config.isProxyTargetClass()为true。

注解实现AOP通知 在AOP注解中一共分为五中类型的通知注解,接下来,我们通过实例,对这五种AOP注解进行讲解 立即下载

相关推荐

使用Docker搭建SearXNG搜索引擎

【代码】使用Docker搭建SearXNG搜索引擎。

janthinasnail的博客 1168

Java常见的spring笔试选择题

Java常见的spring笔试选择题 1、Spring DAO 中最常用的类是() A,JdbcTemplate ,SimpleJdbcTemplate B,SimpleJdbcInsert,SimpleJdbcProcedure C,SimpleJdbcInsert ,SimpleJdbcStoredProc D,SimpleJdbcQuery ,SimpleJdbcExec 正确答案:A 2、Spring AOP 中, 织入(Weaving) 可以在下面什么时间完成() A,全部选项 B,Run tim

hjseo_seg的博客 4752

探索Vortex开源GPGPU:RISC-V SIMT架构(2),指令Decode

本文分析了Vortex RISC-V内核的Decode模块设计。文章详细介绍了指令译码过程,包括操作码、功能码和寄存器字段的提取,以及不同类型指令(R/I/S/B/U/UJ)的立即数处理。重点阐述了基于操作码和功能码的分层译码逻辑,包括ALU运算、分支跳转、系统调用等指令的译码规则。此外,还描述了定制指令的处理机制以及与调度器的握手协议。Decode模块通过组合逻辑实现快速译码,并将结果传递给下级Issue模块,同时协调指令流控制。

weixin_55313207的博客 1792

Spring AOP 之编译期织入、装载期织入、运行时织入

一  配置工厂Bean           通常由应用程序直接使用new创建新对象,为了将对象的创建与使用相分离,采用工厂模式,即应用程序将对象的创建与初始化交给工厂来完成。        一般情况下,应用程序有自己的工厂对象来创建bean,如果将工厂对象交给Springle管理,那么Spring管理的就不是普通的bean,而是工厂Bean。调用getBean()方法,Sprin

单向街的夏天 2万+

android技术--------如何解决弹出键盘只影响当前fragment输入的窗口

题目比较长,也可能有很多人不明所以这东西有啥可写的,简单来说就是实现近似于Android Pad 上QQHD聊天的界面效果,搞了很长的事件,今天终于搞定。 android3.0新加了组件Fragment称之为碎片,对这个一无所知的请自觉补习。今天的阐述将基于此组件。 fragment可以放入activity中,并随activity的生命周期变化而变化,但当相应键盘事件的时候,就比较让人挠头了,

3507

超详细 VMware Horizon 虚拟桌面VDI安装步骤

主要的目的是模拟生产环境中的共享存储。自动桌面相当于共享电脑,大家使用同一个虚拟机,对虚拟机的修改都放在用户的配置文件中,RDS桌面池相当于共享的服务器,可以多人同时连接到服务器上。1:之前已经建立好了NFS的存储,这部分配置好后,以后的虚拟机可以安装到NFS的存储中。2: 使用Composer发布系统可以解决SID,机器名冲突的问题,更重要的可以节约磁盘空间,发布的所有系统可以访问一块磁盘。26: 域选择我们之前建立的域,用户名我输入的是管理员,可以在AD域新建用户点击查找,我这里用的是管理员。

vv12345的博客 1万+

Spring AOP解析(详解动态代理的误区)

Spring是广大java程序员必学的一个框架,Spring的底层源码十分繁琐,封装特别多的方法,今天就从源码的角度浅谈Spring AOP的底层原理。 首先,第一个问题:什么是AOP? 与OOP对比,面向切面,传统的OOP开发中的代码逻辑是自上而下的,在这些自上而下的过程中会产生一些横切性的问题,这些横切性的问题和我们主业务的逻辑关系不大,会散落在代码的各个角落,造成难以维护,AOP的编程性的问...

yechengchao的博客 358

【入门篇】第五章 第一次与 AI Agent 交互

本文介绍了OpenClaw中最基本的用户与AI Agent交互方式,剖析了Agent和Gateway两个核心组件的作用,通过简单示例展示了从用户请求到结果返回的完整执行流程,说明了最小交互过程对验证系统可用性的重要意义,为后续学习复杂任务执行机制奠定基础。

lanyv的博客 512

Spring AOP简介

1、AOP简介 AOP(Aspect Orient Programming),面向切面编程,是面向对象编程 OOP 的一种补充。面向对象编程是从静态角度考虑程序的结构,而面向切面编程是从动态角度考虑程序运行过程。 AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB 的动态代理。 AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续,是

HDW1203的博客 644

Multisim 14.0元件库下载完整指南:从安装到配置

详细介绍Multisim 14.0版本的元件库下载方法,涵盖安装步骤与后续配置流程,帮助用户快速搭建仿真环境。内容覆盖常见问题及解决方案,让multisim元件库下载更高效、稳定。

weixin_34511754的博客 1936

从零构建腾讯滑块验证码破解引擎:逆向工程与实战对抗

本文深入解析腾讯滑块验证码(原天御验证码)的防护机制,包括环境感知层、行为分析层和验证决策层的核心技术。通过JSVMP虚拟机保护、轨迹验证算法和动态加密体系,腾讯验证码实现了高效的人机识别。文章还提供了安全研究实践指南,涵盖环境模拟和验证码识别方案,并探讨了防御对抗的演进趋势与合规研究建议。

rl6adventurer的博客 831

AOP织入时机

http://book.51cto.com/art/200811/97334.htm 对于AOP编程而言,程序的主要逻辑部分和Aspect功能部分的具体实现都可以采用传统的OO技术等实现,这里没有什么新东西。AOP最为特别并使其相对其他方法具有明显优点的部分就在于,它能够以多样的方式将程序中用到的多个方面灵活地织入(Weave)到一起,形成一个完整的应用程序。因而在学习AOP编程时,如何以准

yangzlgg的专栏 2441

第47节:cesium 热力图效果(含源码+视频)

cesium 热力图效果

qq_29384639的博客 1676

Spring AOP 总结一

AOP是一种编程思想,用于将程序中的横切关注点(如事务、日志)从业务逻辑代码中分离出来,以提高代码得可重用性和可维护性。Spring框架对其进行了实现。在Spring中AOP是通过代理模式实现的,即在运行时动态的生成一个代理,这个代理类会拦截目标对象的方法调用,并在方法执行前后添加响应的横切逻辑

java_lover20111106的博客 1064

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

子类重写方法aop切不到_Spring5.0源码深度解析:SpringBean的Aop通知调用链源码分析,小白都能看懂...

点击上方“Java分享吧”,选择“设为星标”优选有价值的技术文献,从我做起源码分析篇章SpringAOP原理探究思考:springAOP底层运用了什么设计模式?生成代理类:代理设计模式、底层五个通知形成调用链采用:责任链设计模式下面我们回顾下SpringAop实现流程:1、配置@EnableAspectJAutoProxy:开启AOP权限2、@Import(AspectJAutoProx...

weixin_39619478的博客 176

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

实例探究Aspectj,解析SentinelResourceAspect

为了学习SentinelResourceAspect,这篇文章里我用Aspectj实现一个AOP实例,一起来看下。 Sentinel 提供了 @SentinelResource 注解用于定义资源,支持 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。 SentinelResourceAspect是Sentinel中的核心切面,Sentinel对限流,拦截等的支持都依...

ting2909的博客 676

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

读书笔记-《Spring技术内幕》(二)AOP的实现

以 Spring AOP 为例,我们只需要学习语言和开发环境这个层面,使用Spring 定义好的注解,编写相关代码并做好配置,就可以实现我们上图右侧想要的效果。具体来说,这是一个遍历定义好的拦截器的过程,经过这些拦截,我们的对象就得到了增强。答案之一便是前面复习的动态代理模式,当然,既然提出了 AOP,那大佬们必然也会给出更多的定义,就像 OOP 的封装、继承、多态一样。),相比之下,Spring AOP 部分没有那么多的类层次设计,但是出现了许多相关的知识点,我们先复习一下,以便后文阅读流畅。

lbqjtyykx的博客 1094

SpringAOP学习--SpringAOP简介及原理

前文对AOP做了介绍,实际项目中,一般不会直接上手手动实现aop,而是使用一些高级封装的aop实现,如SpringAOP。 Spring是一个广泛应用的框架,SpringAOP则是Spring提供的一个标准易用的aop框架,依托Spring的IOC容器,提供了极强的AOP扩展增强能力,对项目开发提供了极大地便利。 前文提到AOP的实现有AspectJ、JDK动态代理、CGLIB动态代理,SpringAOP不是一种新的AOP实现,其底层采用的是JDK/CGLIB动态代理。 JDK动态代理回顾 上一篇简单介绍了

u012098021的博客 6万+

Java程序员校招蚂蚁金服,Java取整数

Part1 SpringIOC 学习Spring最重要的无非是Spring IOC以及Spring AOP,首先咱们把Spring IOC吃透,以下内容将截图展示。 Spring IOC主要学习内容分为以下7点: ①Spring框架 ②Spring lOC容器Bean对象实例化模拟实现 ③Spring IOC容器Bean对象实例化 ④Spring lOC配置文件加载 ⑤Bean的作用域和生命周期 ⑥Spring IOC扫描器 ⑦Spring IOC注入 Part2 SpringAOP核心组件分析

imtokenmax众筹 218

L9:Java框架1 - Spring

【目录】 1.Spring 技术发展 2.Spring 框架设计* 3.Spring AOP 详解* 4.Spring Bean 核心原理* 5.Spring XML 配置原理* 6.Spring Messaging 等技术 7.第9课总结回顾与作业实践 一 技术发展 技术的创新和发展都是为了解决一类问题 二 框架设计 Spring Framework 6大模块 三 Spring AOP详解 循环依赖问题如何处理? 打破依赖 / 超时推出机制 AOP两种方式 字节码增强技术 四 Spring Bea

积累 沉淀 博学 广思 402

面试遇到SpringAOP不要慌

Aspect Oriented Programming(面向切面编程)是一种编程思想。所谓切面可以理解为特定的一些方法。所以AOP可以看成是面向特定的方法进行编程。比如上一篇文章提到的拦截器,就是AOP的体现。它针对特定的方法进行统一的管理,让代码模块化,易于维护。包括ExceptionAdvice、ResponseBodyAdvice(统一异常处理、统一数据返回格式)都运用了AOP的思想。定义一个注解:@Retention(RetentionPolicy.RUNTIME)//表示运行时,仍然存在。

HYY的博客 1212

SpringAop回顾

1:概念 连接点:joinpoint 切入点:pointcut 增强:advice 目标对象:target 织入 wave 代理 proxy 切面 aspect 需要导入依赖:spring-aspect 基于注解的AOP配置 在springxml配置 <!--开启Spring注解扫描--> <context:component-scan base-package="com.qf"/> 四种基本通知,和环绕通知 public class MyAdvi

qq_45935397的博客 297

Spring回顾之AOP实现原理

什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左...

weixin_40792763的博客 188

SpringAOP底层原理 - JDK 动态代理

回顾一下AOP相关概念 SpringAOP的理解和底层原理 补充 引介(Introduction):特殊的增强,动态为类增加方法 织入(Weaving):将增强加入到目标类的过程,织入分为三种时期 编译器:AspectJ (上文讲过) 类加载 运行期:jdk动态代理(实现接口),CGlib(子类,不能用final) 目标对象(Target):原始对象 代理对象(Proxy):加入了增强的对象,是生成的; 切面(Aspect):切点 + 增强 本文要说的就是在运行期间织入的两种实现方式之 jdk动态代理

橘生淮南 328

Java回顾:springAOP、声明式事务

Java回顾:springAOP、声明式事务

m0_56678122的博客 450
上一篇: 回顾SpringAOP中的Advice
下一篇: 回顾aop如何链式调用
至学者
博客等级 码龄9年 180粉丝 773原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值