Spring AOP:静态代理、动态代理和几种常见的aop配置

JDK动态代理和CGLIB动态代理 在SpringAOP中基于动态代理实现功能的增强,也就是动态的生成代理类,在代理类中织入增强的逻辑然后调用目标对象的方法。动态代理中用的比较多的两种:JDK动态代理、CGLIB动态代理。 JDK动态代理 使用JDK的java.lang.reflect.Proxy类的newProxyInstance方法实现的代理。 用一个测试接口看下具体实现: public interface JdkProxyDemoService { void queryTrs(); } @Service public 阅读详情

本文主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习。真诚希望大家给予批评和指导。
本文以自己写的一个简单Code为例,主要逻辑结构及说明信息依code中的注释内容为说明,所以可能出现 many codes little explianations.


  1. AOP的常见概念
  2. 静态代理
  3. jdk动态代理
  4. Aspectj and Aspectjweaver
  5. aop-config
  6. CGLIB aop-config
  7. AOP动态代理配置
  8. AOP自动识别动态代理配置

1. AOP常见概念

  • Cross Cutting Concern :
    横切性关注点,补充我们OOP纵向编写的补充,可以理解成遍布在系统的处理流程中的,一种独立的服务。
  • Aspect : 对我们上面的Cross Cutting Concern 的一种模块化,也就是将其封装成一个类。
  • Advice : 对关注点的具体实现,在切面的某个特定的连接点( Joinpoint )上执行的动作。其含有多种通知类型:
    之前、返回之后、抛出之后、环绕通知。具体的可以参考文档。
  • Pointcut : 定义了这个Adivce 应用到那些 Joinpoint 上。
  • Jointpoint : 是 Advice 在应用程序上的执行点或者时机,对Spring来说,它就是方法调用。
  • Weave : 将 Advice 应用到Target Object 上的整个过程叫织入。
  • Target Object : Advice应用的对象。

2. 项目结构

这里写图片描述


3 静态代理和动态代理showing

接口:com.qian.subject.Subject –目标类RealSubject和代理类要实现的接口。
目标类: com.qian.realsubject.RealSubject
静态代理类: com.qian.staticproxy.SubjectStaticProxy
动态代理类: com.qian.dynamicproxy.SubjectDanamicProxy

package com.qian.subject;
/**
 * 实际类RealSubject和代理类要实现的接口;
 * @author Administrator
 */
public interface Subject {

    public void addSub(String name, String password);

    public String findSub(String id);

}
package com.qian.realsubject;
import com.qian.subject.*;

/**
 * Subject的实现类,并重写方法
 * @author Administrator
 *
 */
public class RealSubject implements Subject {

    public void addSub(String name, String password) {
        System.out.println("RealSubject.addSub()   "+ name+"  "+ password);
    }

    public String findSub(String id) {
        System.out.println("RealSubject.findSub()  "+ id);
        return "realSubject.findSub()";
    }

}
package com.qian.staticproxy;

import com.qian.subject.Subject;

public class SubjectStaticProxy implements Subject {
    //Remark: 拿到实际对象的引用;
    private Subject realSubject;

    //这里我们通过构造函数拿到;
    public SubjectStaticProxy(Subject realSubject){
        this.realSubject = realSubject;
    }
    public void addSub(String name, String password) {
        System.out.println("staticProxy do something before realSubject.add()");
        //调用实际对象的方法
        realSubject.addSub(name, password);
    }

    public String findSub(String id) {
        System.out.println("staticProxy do something before realSubject.findSub()");
        return realSubject.findSub(id);
    }

}
package com.qian.danamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class SubjectDanamicProxy implements InvocationHandler {

    //实际要传入的realSubject;
    private Object realSubject;

    public Object getSubjectProxy(Object realSubject){
        this.realSubject = realSubject;
        //都是realSubject的;
        Object proxy = Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), 
                realSubject.getClass().getInterfaces(), 
                this);
        //为了看看这个proxy和invoke(proxy)是否一样
        System.out.println("--proxy=Prox.new...() is "+proxy.getClass().getName());
        return proxy;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("--proxy in invoke parameters is "+proxy.getClass().getName());
        checkInfo();
        Object result = method.invoke(realSubject, args);       
        return result;
    }

    private void checkInfo(){
        System.out.println("Doing some checking things before method invocation");
    }
}

4 Spring实现AOP的方式之Aspectj注解

Aspectj类:com.qian.springaopaspectj.CheckInfoAspect
xml文件:applicationContextAspectj.xml

package com.qian.springaopaspectj;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 将 代理类中 都要做得检查操作(横切性关注点模块化)
 * @author Administrator
 *
 */
@Aspect //对横切性关注点的模块化;
public class CheckInfoAspect {

    //定义advice应用到那些连接点上,也就是advice在应用程序上自行的点或者时机
    //poincuName()就是给这个poincut起个名;
    @Pointcut("execution(* add*(..)) || execution(* find*(..))")
    private void poincutName(){}

    //advice也就是关注点的具体实现;before在连接点JointPoint的前面使用
    @Before("poincutName()")
    public void checkInfo(){
        System.out.println("Doing some checking things before method invocation");
    }

}
<?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:tx="http://www.springframework.org/schema/tx"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.3.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">


    <!-- 告诉JVM 我们用了aspectj的 annotation -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <bean id="realSubject" class="com.qian.realsubject.RealSubject"/>
    <bean id="checkInfoAspect" class="com.qian.springaopanno.CheckInfoAspect"/>



</beans>

5 Spring实现AOP的方式之aop-config

目标类:com.qian.realsubject.RealSubject
Advice类:com.qian.springaopxml.CheckInfoAspectXml
xml文件: applicationContextConfig.xml

package com.qian.springaopxml;

/**
 * 模拟将遍布在系统流程中的检查信息(关注点)模块化成一个Aspect
 * @author Administrator
 *
 */
public class CheckInfoAspectXml {

    public void checkInfo(){
        System.out.println("Doing some checking things before method invocation");
    }
}
<?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:tx="http://www.springframework.org/schema/tx"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.3.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">


    <bean id="realSubjectCGLIB" class="com.qian.realsubject.RealSubjectCGLIB"/>

    <bean id="checkInfoAspectXml" class="com.qian.springaopxml.CheckInfoAspectXml"/>

    <aop:config>
        <aop:aspect id="checkInfoAspectXml" ref="checkInfoAspectXml">

            <aop:pointcut expression="execution(* com.qian.realsubject.RealSubjectCGLIB.add*(..))||execution(* find*(..))" id="pointcut"/>

            <aop:before method="checkInfo" pointcut-ref="pointcut"/>

        </aop:aspect>
    </aop:config>


</beans>

6 插曲,当目标类没有继承接口时,我们用CGLIB,并配置aop-config

类:com.qian.realsubject.RealSubjectCGLIB
Advice类:com.qian.springaopxml.CheckInfoAspectXml
xml文件: applicationContextConfigCGLIB.xml

package com.qian.realsubject;

/**
 * 没有实现任何接口,我们用CGLIB来动态代理它
 * @author Administrator
 *
 */
public class RealSubjectCGLIB {

    public void addSub(String name, String password) {
        System.out.println("RealSubject.addSub()   "+ name+"  "+ password);
    }

    public String findSub(String id) {
        System.out.println("RealSubject.findSub()  "+ id);
        return "realSubject.findSub()";
    }

}
<?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:tx="http://www.springframework.org/schema/tx"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.3.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">


    <bean id="realSubjectCGLIB" class="com.qian.realsubject.RealSubjectCGLIB"/>

    <bean id="checkInfoAspectXml" class="com.qian.springaopxml.CheckInfoAspectXml"/>

    <aop:config>
        <aop:aspect id="checkInfoAspectXml" ref="checkInfoAspectXml">

            <aop:pointcut expression="execution(* com.qian.realsubject.RealSubjectCGLIB.add*(..))||execution(* find*(..))" id="pointcut"/>

            <aop:before method="checkInfo" pointcut-ref="pointcut"/>

        </aop:aspect>
    </aop:config>


</beans>

7 Spring实现AOP的方式之POJO

目标类 : com.qian.realsubject.RealSubjectBean
Advice类: com.qian.springaopproxy.RealSubjectBeanHelper –实现了接口 AfterReturningAdvice, MethodBeforeAdvice
xml文件:applicationContextProxy.xml

package com.qian.realsubject;

/**
 * 为了说明 CGLIB 和spring 可以在 JDK动态代理和CGLIB切换
 * 定义了一个没有实现任何借口的普通类;
 * @author Administrator
 *
 */
public class RealSubjectBean {

    private String subName;
    private String password;

    public String getSubName() {
        return subName;
    }

    public void setSubName(String subName) {
        this.subName = subName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void addSubBean() {
        System.out.println("RealSubjectBean.addSubBean()   "+ subName+"  "+ password);
    }

    public String findSubBean(String subName) {
        System.out.println("RealSubjectBean.findSubBean()  "+ subName);
        return "realSubjectBean.findSubBean()";
    }

}
package com.qian.springaopproxy;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;

/**
 * 使用spring 典型的动态代理来处理
 * @author Administrator
 *
 */
public class RealSubjectHelper implements AfterReturningAdvice, MethodBeforeAdvice {

    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
        System.out.println(" RealSubjectHelper BeforMehtod: checking information");
    }

    public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
        System.out.println(" RealSubjectHelper AfterMehtod: checking information");
    }

}
<?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:tx="http://www.springframework.org/schema/tx"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.3.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

    <!-- (1)  注册Bean RealSubjectBean 和实现了 MethodBeforeAdvice AfterReturningAdvice接口的 RealSubjectHelper-->

    <bean id="realSubjectBean" class="com.qian.realsubject.RealSubjectBean">
        <property name="subName" value="zhangsan"/>
        <property name="password" value="zhangsan123"/>
    </bean>

    <bean id="realSubjectHelper" class="com.qian.springaopproxy.RealSubjectHelper"/>


    <!-- (2) 使用正则表达式来表示切点Pointcut 使用类 JdkRegexpMethodPointcut-->

    <bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
        <property name="pattern" value=".*find.*"/>
    </bean>


    <!-- (3) 将横切点的具体实现 Advice 和  切点 Pointcut 联合起来 使用类 DefaultPointcutAdvisor-->
    <!--  
    <bean id="pointcutAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="pointcut" ref="pointcut"/>
        <property name="advice" ref="realSubjectHelper"/>
    </bean>
    -->
    <bean id="pointcutAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <constructor-arg name="pointcut" ref="pointcut"/>
        <constructor-arg name="advice" ref="realSubjectHelper"/>
    </bean>


    <!--  (4) 生成目标对象RealSubjectBean的代理对象 使用类  ProxyFactoryBean -->

    <bean id="realSubjectBeanProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 目标对象 target -->
        <property name="target" ref="realSubjectBean"/>
        <!-- 拦截方法 -->
        <property name="interceptorNames">
            <list>
                <value>pointcutAdvisor</value>
            </list>
        </property>
    </bean>


</beans>

对 7中的xml进行简化

xml文件: applicationContextProxyV2.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:tx="http://www.springframework.org/schema/tx"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-4.3.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

    <!-- (1)  注册Bean RealSubjectBean 和实现了 MethodBeforeAdvice AfterReturningAdvice接口的 RealSubjectHelper-->

    <bean id="realSubjectBean" class="com.qian.realsubject.RealSubjectBean">
        <property name="subName" value="zhangsan"/>
        <property name="password" value="zhangsan123"/>
    </bean>

    <bean id="realSubjectHelper" class="com.qian.springaopproxy.RealSubjectHelper"/>


    <!-- (2) 使用正则表达式来表示切点Pointcut 和 横切点的具体实现Advice自动联合 使用类 RegexpMethodPointcutAdvisor-->

    <bean id="pointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="pattern" value=".*find.*"/>
        <property name="advice" ref="realSubjectHelper"/>
    </bean>


    <!--  (3) 生成目标对象RealSubjectBean的代理对象 使用类自动代理生成器 DefaultAdvisorAutoProxyCreator-->

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

</beans>

8 最主要的Client类

package com.qian.client;

import com.qian.realsubject.RealSubject;
import com.qian.realsubject.RealSubjectBean;
import com.qian.realsubject.RealSubjectCGLIB;
import com.qian.staticproxy.SubjectStaticProxy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.qian.danamicproxy.SubjectDanamicProxy;
import com.qian.subject.Subject;

/**
 * Client主测试类
 * @author Administrator
 *
 */
public class Client {

    //最通俗易懂的办法 但是耦合度太高了
    public static void subjectImpl(){
        Subject subject = new RealSubject();
        subject.addSub("qian", "520");
        subject.findSub("511");
    }

    // 静态代理
    public static void staticProxy(){

        Subject subject = new SubjectStaticProxy(new RealSubject());
        subject.addSub("name", "password");
        subject.findSub("123");
    }

    // 动态代理
    public static void dynamicProxy(){

        Object proxy = new SubjectDanamicProxy().getSubjectProxy(new RealSubject());
        Subject subject = (Subject)proxy;
        subject.addSub("zhangsan", "pass123");
        subject.findSub("134");
    }

    //使用 Aspectj.jar 和Aspectjweaver.jar 进行注释 推崇
    public static void springaopAspectj(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextAspectj.xml");
        Subject subject = (Subject) context.getBean("realSubject");
        subject.addSub("spring", "aop");
        subject.findSub("1231");
    }

    //使用spring的aop-config进行配置、推崇
    public static void springaopConfig(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextConfig.xml");
        Subject subject = (Subject) context.getBean("realSubject");
        subject.addSub("spring", "aop");
        subject.findSub("1231");
    }

    //对没有实现接口的类使用CGLIB 并使用spring的aop-config进行配置
    public static void springaopConfigCGLIB(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextAopConfigCGLIB.xml");
        RealSubjectCGLIB subject = (RealSubjectCGLIB) context.getBean("realSubjectCGLIB");
        subject.addSub("spring", "aop");
        subject.findSub("1231");
    }

    //spring AOP动态代理
    public static void springaopProxy(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextProxy.xml");
        RealSubjectBean subjectBean = (RealSubjectBean) context.getBean("realSubjectBeanProxy");
        subjectBean.addSubBean();
        subjectBean.findSubBean("springaop4");
    }

    //spirng AOP自动进行匹配的动态代理
    public static void springaopProxyV2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextProxyV2.xml");
        RealSubjectBean subjectBean = (RealSubjectBean) context.getBean("realSubjectBean");
        subjectBean.addSubBean();
        subjectBean.findSubBean("springaop4");
    }
    public static void main(String[] args) {
        //subjectImpl();
        //staticProxy();
        //dynamicProxy();
        //springaopConfig();
        //springaopConfigCGLIB();
        //springaopProxy();
        //springaopProxyV2();
    }

}

结果都是预期的结果这里就不显示了。


本project使用的是Maven建的、所以pom.xml如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>springaop</groupId>
  <artifactId>SpringAop</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.3.0.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.3.0.RELEASE</version>
    </dependency>

    <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
    </dependency>

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.5</version>
    </dependency>

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.0</version>
    </dependency>

  </dependencies>
</project>

如果有想找完整版的src文件的朋友,可以留邮箱、


Thank you for your consideration. Thanks everyone. And I am grateful to those who give any comments or suggestions in the futrue.

【Spring】Spring第二天 - AOP 详解、动态代理设计模式(JDK和cglib) 一.AOP 1.AOP:中文名称面向切面编程 2.英文名称:(Aspect Oriented Programming) 3.正常程序执行流程都是纵向执行流程 3.1 又叫面向切面编程,在原有纵向执行流程中添加横切面 3.2 不需要修改原有程序代码 3.2.1 高扩展性 3.2.2 原有功能相当于释放了部分逻辑.让职责更加明确. 4.面向切面编程是什么? 4.1 在程序原有纵向执行流程中,针对某一... 阅读详情

相关推荐

Hadoop实战:用MapReduce分析YouTube视频数据集(附完整代码)

本文提供了一个完整的Hadoop MapReduce实战教程,指导读者使用MapReduce框架分析YouTube视频数据集,统计不同视频类别的数量分布。教程涵盖从数据获取、预处理、HDFS操作到Java代码编写、作业提交及结果可视化的全流程,并附有完整代码,帮助开发者深入理解分布式计算思想。

lilh34434的博客 198

Spring Boot 自动配置 : AopAutoConfiguration & 源码解析

https://www.jianshu.com/p/484bae9d1fb2 概述 自动配置AopAutoConfiguration类的主要任务是根据配置参数使用注解@EnableAspectJAutoProxy。 该自动配置类通过注解声明了自己生效的条件是 : 以下类必须存在于classpath : EnableAspectJAutoProxy Aspect Advice An...

z69183787的专栏 2271

aubo i5 + realsense D435i识别抓取实践二

aubo i5 + realsense D435i识别抓取实践二前言一、手眼标定是什么?二、标定软件安装1.aruco_ros安装2.vision_visp安装3.easy_handeye安装4.realsense驱动安装5.安装realsense ROS软件包三、配置1.launch文件修改2.打印二维码四、手眼标定1.启动launch文件2.标定步骤3.发布tf关系 前言 前面配置好了aubo机械臂的ROS软件包,机械臂可以正常运行后,接下来我们进行机械臂与相机的手眼标定。手眼标定分为eye_on_ha

转角 6373

spring-aop与auto

/ @Autowired自动装配原理:首先会根据byType方式,进行自动装配,如果能唯一匹配,直接执行自动装配,如果不能唯一匹配(存在同类型多个实例对象),会再次尝试使用byName方式,根据当前实体属性名,到容器中进行匹配(容器中bean的id值),如果能唯一匹配,仍会执行自动装配,如果匹配失败,直接抛出异常。根据实例属性的类型,到容器中,根据类型进行唯一匹配,如果可以匹配到对应类型的bean的实例,就会执行自动装配,如果不能唯一匹配(同类型的bean有多个),会报错,并装配失败。...

hshshshh的博客 432

YOLO项目从零开始:超详细运行教程(图文保姆级教学)

至此,我们已经完整跑通了YOLO项目的安装与启动流程,无论你是零基础小白还是刚入门的AI新兵,只要按部就班操作,也能轻松实现目标检测项目的落地。

一键难忘的博客 4797

加速访问Cloudflare的网站的解决方案

本文主要介绍了加速访问Cloudflare的网站的解决方案,希望能对大家有所帮助。通过软件计算得到最快的IP地址的效果图如下图所示,具体解决方案参考下文。 在这里插入图片描述 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 1万+

Spring的AOP原理

Spring的AOP是我们在开发中比较常用的一种思想,比如日志的数据等,那Spring是如何通过配置来创建AOP的呢 本文主要通过注解配置来讲解 解析切面类 我们在使用注解配置AOP的时候通常需要@EnableAspectJAutoProxy这个注解来开启AOP 那其实这个注解里的@Import注解里有个AspectJAutoProxyRegistrar类来注册对应的BeanDefinition 这个类里注册了一个AnnotationAwareAspectJAutoProxyCreator这个Bea

小年的博客 702

通用抓取算法AnyGrasp(Graspnet)——本地部署并测试自定义输入数据

背景:GraspNet在数据采集方面,首先将相机固定到机械臂末端,对同一个场景拍摄256个不同的角度,同时场景中的每个物体都会提前采集好3D模型,之后将其投射到仿真环境中,在仿真环境中,对抓取位姿进行打标签,如此完成数据的采集。在运行官方的测试示例时,使用的是路径下的输入数据,可以分析下。color.png(输入):rgb图像(输出):输出的生成抓取位姿的图像depth.png(输入):和当前rgb图像对应的深度图像(保存格式是单通道uint16)meta.mat。

boss-dog 1324

使springAOP生效不一定要加@EnableAspectJAutoProxy注解

本文主要分析了在springboot环境下,不加@EnableAspectJAutoProxy注解springAOP仍然生效的问题。为了保险期间请一律加上@EnableAspetJAutoProxy注解。AopAutoConfiguration类等同于@EnableAspectJAutoProxy注解;spring.aop.auto=ture/false属性可以控制AopAutoConfiguration类是否生效;

band_mmbx的博客 947

【RT-DETR有效改进】利用ASF-YOLO改进特征融合层(附代码 + 详细教程)

本文给大家带来的改进机制是ASF-YOLO(发布于2023.12月份的最新机制),其是特别设计用于细胞实例分割。这个模型通过结合空间和尺度特征,提高了在处理细胞图像时的准确性和速度。在实验中,ASF-YOLO在2018年数据科学竞赛数据集上取得了卓越的分割准确性和速度,达到了0.91的box mAP(平均精度),0.887的mask mAP,以及47.3FPS的推理速度,效果非常的好,这个结构本来是用于分割的,我将其移植到了目标检测的模型上,所以其可以适用于分割和目标检测。

Snu77的博客 2292

GEE:关于遥感生态指数(RSEI)的若干疑问

本文记录了若干关于在 Google Earth Engine (GEE)平台上,计算基于主成分分析(PCA)的遥感生态指数(RSEI)的问题。并记录了解决这些问题的一些答案。问题包括,主成分分析的特征值的正负,主成分的占比,去云后空值像素的处理方法,异常值处理方法,如何看载荷等。

养乐多的博客 3416

​温故知新——Spring AOP

SpringAOP面向切面编程,相信大家都不陌生,它和SpringIOC是Spring赖以成名的两个最基础的功能。在咱们平时的工作中,使用IOC的场景比较多,像咱们平时使用的@Controller、@Service、@Repository、@Component、@Autowired等,这些都和IOC相关。...

wuxiaopengnihao1的博客 313

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Spring全家桶面试题(一)之Spring Framework(六)

AOP(Aspect-Oriented Programming),一般称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理等。AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想。 **OOP(面向对象编程)**针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。

TPH_BETTER.的博客 172

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

讲解AOP代理和重点解析Spring AOP代理(动态代理),看完秒懂!!!!

上一章我们生动形象的讲了什么是AOP面向切面编程以及代码示例,有不明白的小伙伴可以去看看(https://blog.youkuaiyun.com/qq_32317661/article/details/82878679),承上启下,这一篇讲一下Spring AOP代理的两种方式和它的大致原理。 一、AOP代理 AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ;而动态代理则以Spring...

healer的博客 8317

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【Spring Boot】Spring AOP动态代理,以及静态代理

定义 MethodInterceptor 并重写 intercept 方法, intercept 于增强标方法,和JDK动态代理中的 invoke 方法类似//?标对象, 即被代理对象@Override// 代理增强内容System.out.println("我是中介, 开始代理");//通过反射调?被代理类的方法//代理增强内容System.out.println("我是中介, 代理结束");

2509_92430413的博客 1760

Spring AOP原理之动态代理

什么是代理? 指为一个目标对象提供一个代理对象, 并由代理对象控制对目标对象的引用. 使用代理对象, 是为了在不修改目标对象的基础上, 增强目标对象的业务逻辑. 静态代理 静态代理的特点是, 为每一个业务增强都提供一个代理类, 由代理类来创建代理对象. 下面我们通过静态代理来实现对转账业务进行身份验证. (1) 转账业务 public interface IAccountService { ...

Tyshawn的博客 5万+

Spring-AOP详解(AOP概念,原理,动态代理,静态代理)

重点:1.Spring-Framework的proxytargetclass默认值为false,所以Spring-Framework,JDK和CGLIB两个代理都使用 2.而Spring-Boot需要区分版本:对于Spring-Boot 2.xxx版本,proxytargetclass默认值也为false.所以,Spring-Boot 2.xxx版本也是JDK和CGLIB两个代理都使用,而Spring-Boot 3.xxx版本proxytargetclass默认值则为true,所以Spring-Boot 3

robin_suli的博客 1798

【Spring-AOP基础】深入浅出Spring-AOP(从动态代理到Spring AOP)

AOP(Aspect Oriented Programming) 1.概念 AOP:全称是 Aspect Oriented Programming即:面向切面编程。

ATFWUS的博客 11万+

静态代理、动态代理、spring动态代理(Spring AOP面向切面编程)、spring动态代理注解版

目录 静态代理 列:实现静态代理 代理接口User.java 目标对象 实际业务逻辑实现方法UserImpl.java 代理类UserProxy.java 测试 动态代理 列: 实现动态代理 创建po对象 创建dao 创建代理类MyProxy.java 测试 Spring Aop 面向切面编程(spring动态代理) 列:aop练习 导包 User.java ...

Birdlun的博客 2654

JavaEE进阶(11)Spring AOP:AOP概述、Spring AOP快速入门、详解)、原理(代理模式:静态代理、动态代理:JDK动态代理、CGLIB动态代理)、源码剖析(了解)

AOP概述、Spring AOP快速入门、Spring AOP详解(涉及的核心概念、通知类型、多个AOP程序的执行顺序、@PointCut、切面优先级 @Order、切点表达式、自定义注解)、Spring AOP原理(代理模式——静态代理 、动态代理:JDK动态代理、CGLIB动态代理)、Spring AOP源码剖析(了解)

m0_74343467的博客 1564

Spring动态代理的两种区别

Spring的面向切面编程也是基于动态代理来实现的 静态代理:也就是自己手动创建的代理对象 动态代理:也就是在程序运行中通过配置参生的 那么Spring的AOP也就是面向切面编程,就是基于动态代理来实现的,通过代理原始类增加额外功能,我们可以将额外功能一次定义然后配合切点达到多次使用的效果,比如 做日志啊 事物啊 时间啊等等…提高了复用性 开发效率. 那么在Spirng当中动态代理有两种 ...

qq_42807370的博客 1万+

Spring AOP与静态代理/动态代理

在梳理Aop的原理之前,我们先了解一下代理模式,其中分静态代理与动态代理。例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:以下是本篇文章正文内容,下面案例可供参考我们一开始简单的初步认识了下代理模式,其中常见的实现方式有静态代理与动态代理,同时写了打印机🖨️的调用时机代码。接着我们思考🤔代理模式和我们使用spring aop有什么联系?简单的了解aop 与spring aop的实现方式。

Bruce__taotao的博客 2073

别再说 Spring AOP 默认用的是 JDK 动态代理

话不多说,发车! 说下 AOP AOP,Aspect Oriented Programming,面向切面编程。 将一些通用的逻辑集中实现,然后通过 AOP 进行逻辑的切入,减少了零散的碎片化代码,提高了系统的可维护性。 具体是含义可以理解为:通过代理的方式,在调用想要的对象方法时候,进行拦截处理,执行切入的逻辑,然后再调用真正的方法实现。 例如,你实现了一个 A 对象,里面有 addUser 方法,此时你需要记录该方法的调用次数。 那么你就可以搞个代理对象,这个代理对象也提供了 addUser.

HongYu012的博客 3563

JDK动态代理、Cglib动态代理及Spring AOP

Java中的JDK动态代理是一种通过反射机制生成代理对象的技术,使得我们能够在运行时动态地创建某个接口的代理类,而无需手动编写实现类。JDK动态代理通常用于横切关注点(如日志、事务管理、安全性等)在方法调用前后进行处理,而不需要修改目标类的源代码。JDK 动态代理特点只能代理实现了接口的类或对象。在运行时动态生成代理类,避免了手动创建静态代理类的繁琐。使用简单,适用于代理接口的场景。应用场景:适合需要对接口进行动态代理的场景,如一些简单的业务逻辑。Cglib 动态代理特点。

m0_67391870的博客 1120
上一篇: 初识 Maven
下一篇: Hibernate: 三种状态和CRUD四种操作
Coder-Qian
博客等级 码龄11年 63粉丝 73原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值