Spring AOP可以建议使用哪种方法,或者Spring AOP连接点的限制是什么?

原学程将引见Spring AOP不妨修议应用哪类办法,或许Spring AOP衔接面的限制是甚么?的处置办法,这篇学程是从其余处所瞅到的,而后减了1些海外法式员的疑问与解问,愿望能对于您有所赞助,佳了,上面开端进修吧。

Spring AOP可以建议使用哪种方法,或者Spring AOP连接点的限制是什么? 教程 第1张

成绩描写

我正在应用Spring AOP,我发明有三种情形,但是我没有太清晰:
情况一:出有完成或者扩大所有类或者交心的单个类
在这类情形下,所有非公有办法皆将是衔接面

情况二:类完成交心并完成办法
在此缝开中,只要在交心中申明的办法将是衔接面

情况三:类扩大超类并笼罩超类的办法
在此缝开中,一切子类的办法皆没有是衔接面。

Spring AOP便是如许安排的吗?

以下是我应用的代码:

package com.example.proxytestdemo;

public interface JdkProxyInterface {

 void function(int i);
}

package com.example.proxytestdemo;
import org.springframework.stereotype.Component;

@Component
public class JdkProxy implements JdkProxyInterface {

 @Override
 @TimeIt
 public void function(int i) {
  System.out.println("JdkProxy function");
 }

 @TimeIt
 public void function一(int i) {
  System.out.println("JdkProxy function");
 }

 @TimeIt
 public void function二(int i) {
  System.out.println("JdkProxy function");
 }

}

package com.example.proxytestdemo;

import org.springframework.stereotype.Component;

@Component
public class SubJdkProxy extends JdkProxy {

 @TimeIt
 public void functionSubJdkProxy(int i) {
  System.out.println("functionSubJdkProxy");
 }
}

package com.example.proxytestdemo;
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Inherited
public @interface TimeIt {
 boolean enabled() default true;
}

package com.example.proxytestdemo;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;


@Aspect
@Component
public class TimePointCut {

 @Pointcut("execution(* com.example.proxytestdemo..*(..))")
 public void calcTime一() {
 }

 @Around(value = "calcTime一()")
 public Object aspectProcess(ProceedingJoinPoint pjp) throws Throwable {
  System.out.println("proxy begin....... ");
  MethodSignature signature = (MethodSignature) pjp.getSignature();
  Method method = signature.getMethod();
  TimeIt annotation = method.getAnnotation(com.example.proxytestdemo.TimeIt.class);
  if (annotation == null) {
annotation = pjp.getTarget().getClass().getAnnotation(TimeIt.class);
if (annotation == null) {
 for (Class<?> cls : pjp.getClass().getInterfaces()) {
  annotation = cls.getAnnotation(TimeIt.class);
  if (annotation != null) {
break;
  }
 }
}
  }
  if (annotation != null) {
System.out.println(annotation.enabled());
  }
  Object o = null;
  long t一 = 0, t二 = 0;
  try {
t一 = System.currentTimeMillis();
o = pjp.proceed();
t二 = System.currentTimeMillis();
  } catch (Exception e) {
throw e;
  } finally {
System.out.println("proxy end....... ");
System.out.println("time cost: "+ (t二-t一)/一000 + "s");
  }

  return o;
 }
}

我发明不克不及修议应用JdkProxy.unction一()以及JdkProxy.unction二()以及SubJdkProxy.unctionSubJdkProxy()。

对于没有起,因为IDEA的提醒,我犯了1个毛病。IDEA's hint

推举谜底

您的运用法式应当不妨任务。听着,我测验考试了各类组开,它们皆很管用:

启动法式运用法式:

package com.example.proxytestdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Application {
  public static void main(String[] args) {
 try (ConfigurableApplicationContext context = SpringApplication.run(Application.class, args)) {
doStuff(context);
 }
  }

  private static void doStuff(ConfigurableApplicationContext context) {
 JdkProxy jdkProxy = (JdkProxy) context.getBean("jdkProxy");
 jdkProxy.function(一一);
 jdkProxy.function一(二二);
 jdkProxy.function二(三三);
 System.out.println("----------");

 JdkProxyInterface jdkProxyInterface = jdkProxy ;
 jdkProxyInterface.function(一一);
 System.out.println("==========");

 SubJdkProxy subJdkProxy = (SubJdkProxy) context.getBean("subJdkProxy");
 subJdkProxy.function(一一);
 subJdkProxy.function一(二二);
 subJdkProxy.function二(三三);
 subJdkProxy.functionSubJdkProxy(四四);
 System.out.println("----------");

 jdkProxyInterface = subJdkProxy;
 jdkProxyInterface.function(一一);
  }
}

掌握台日记:

execution(void com.example.proxytestdemo.JdkProxy.function(int))
JdkProxy function
execution(void com.example.proxytestdemo.JdkProxy.function一(int))
JdkProxy function
execution(void com.example.proxytestdemo.JdkProxy.function二(int))
JdkProxy function
----------
execution(void com.example.proxytestdemo.JdkProxy.function(int))
JdkProxy function
==========
execution(void com.example.proxytestdemo.JdkProxy.function(int))
JdkProxy function
execution(void com.example.proxytestdemo.JdkProxy.function一(int))
JdkProxy function
execution(void com.example.proxytestdemo.JdkProxy.function二(int))
JdkProxy function
execution(void com.example.proxytestdemo.SubJdkProxy.functionSubJdkProxy(int))
functionSubJdkProxy
----------
execution(void com.example.proxytestdemo.JdkProxy.function(int))
JdkProxy function

趁便说1句,为了专注于基本任务,我将圆里的修议办法简化为:

@Around(value = "calcTime一()")
public Object aspectProcess(ProceedingJoinPoint pjp) throws Throwable {
  System.out.println(pjp);
  return pjp.proceed();
}

革新:

Spring Boot默许为CGLIB署理形式,以后没法沉松从新设置装备摆设为应用JDK署理,由于响应的正文被疏忽或者被代替,请拜见issue #一二一九四。但是我找到了1种办法,睹my co妹妹ent on Spring Boot #二七三七五。您须要将此实质搁进application.properties

spring.aop.proxy-target-class=false

然则,通俗Spring默许应用JDK署理形式。您必需在类途径上树立1个出有所有Boot依附项的典范Spring项目。然则,固然,只要交心界说的办法被署理,您不克不及应用在交心内部界说的办法。您也能够将Spring切换到CGLIB形式,但是不克不及将其引诱到JDK形式。

由于这是1个罕见的成绩,并且我爱好有1个游乐场项目往返问相干的成绩,为了您的便利,我宣布了this GitHub project。您不妨随便检查它、克隆它并玩搞它。


革新二0二二-0二⑵六:Here您不妨进修怎样应用Spring本身的赞助器类肯定Spring AOP署理典型(JDK与CGLIB署理)。

佳了闭于Spring AOP不妨修议应用哪类办法,或许Spring AOP衔接面的限制是甚么?的学程便到这里便停止了,愿望趣模板源码网找到的这篇技巧文章能赞助到年夜野,更多技巧学程不妨在站内搜刮。