[英]Spring Bean Config
我正在學習帶有注釋和 xml 配置的 bean AOP,但 Spring 不會創建 bean。
界面
package com.spring.studying.SpringAop.FrameworkService.AspectJAnnotation;
public interface Artist {
void perform();
}
吉他 Class
package com.spring.studying.SpringAop.FrameworkService.AspectJAnnotation;
import org.springframework.stereotype.Component;
@Component("grammyGuitarist")
public class GrammyGuitarist implements Artist{
@Override
public void perform() {
System.out.println("Start to play guitar");
}
public void playGuitar(String brand)
{
System.out.println("Get Guitar "+brand);
}
public void rest()
{
System.out.println("zzZZ!!!!");
}
}
紀錄片導演
package com.spring.studying.SpringAop.FrameworkService.AspectJAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component(value="documentaries")
public class Documentarist {
private GrammyGuitarist guitarist;
public void executed()
{
guitarist.playGuitar("LakeWood");
guitarist.perform();
guitarist.rest();
}
@Autowired
public void setGuitarist(GrammyGuitarist guitarist) {
this.guitarist = guitarist;
}
}
建議 Class
package com.spring.studying.SpringAop.FrameworkService.AspectJAnnotation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component("annotatedAdvice")
@Aspect
public class AnnotatedAdvice {
@Pointcut("execution(* rest*(..)) && args(brand)")
public void restExecution(String brand)
{
}
@Pointcut("bean(grammyGuitarist)")
public void isGrammyGuitarist()
{
}
@Before("restExecution(brand) && isGrammyGuitarist")
public void simpleBeforeAdvice(JoinPoint joinPoint , String brand)
{
System.out.println("Before Advice processing");
System.out.println("Playing guitar :" + brand);
System.out.println("Executing :"+ joinPoint.getSignature().getDeclaringTypeName() +" "+joinPoint.getSignature().getName());
}
}
演示 Class
package com.spring.studying.SpringAop.FrameworkService.AspectJAnnotation;
import org.springframework.context.support.GenericXmlApplicationContext;
import java.util.Arrays;
public class AspectJAnnotationDemo {
public static void main(String[] args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("aop-aspectj-annotation-style.xml");
ctx.refresh();
Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);
Documentarist documentarist = ctx.getBean("documentaries",Documentarist.class);
documentarist.executed();
}
}
我的 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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:annotation-config/>
<context:component-scan base-package="com.spring.studying.SpringAop"/>
<aop:aspectj-autoproxy/>
</beans>
我的 bean 都不是僅從 spring 中創建的 6 個默認 bean。
我嘗試用標簽創建 bean,它工作正常。 只是不知道為什么我的代碼不適用於注釋。
restExecution
@Pointcut
是錯誤的,因為rest
的GrammyGuitarist
方法不采用任何 arguments。 playGuitar
方法接受brand
參數,所以你需要稍微改變你的切入點:
@Component("annotatedAdvice")
@Aspect
public class AnnotatedAdvice {
@Pointcut("execution(* play*(..)) && args(brand)")
public void playExecution(String brand) {
}
@Pointcut("bean(grammyGuitarist)")
public void isGrammyGuitarist() {
}
@Before("playExecution(brand) && isGrammyGuitarist()")
public void simpleBeforeAdvice(JoinPoint joinPoint, String brand) {
System.out.println("Before Advice processing");
System.out.println("Playing guitar :" + brand);
System.out.println("Executing :" + joinPoint.getSignature().getDeclaringTypeName() + " " + joinPoint.getSignature().getName());
}
}
當你這樣做時,方面確實會被創建,但你會開始得到異常:
Bean named 'grammyGuitarist' is expected to be of type 'com.example.demo.aspect.GrammyGuitarist' but was actually of type 'jdk.proxy2.$Proxy14'
這是因為GrammyGuitarist
實現了一個接口, 在這種情況下Spring AOP
使用 JDK 動態代理
最簡單的解決方案是強制使用 CGLIB 代理。 為此,您需要在方面上方添加注釋:
@EnableAspectJAutoProxy(proxyTargetClass = true)
之后,程序將給出預期的結果:
annotatedAdvice
documentaries
grammyGuitarist
org.springframework.aop.config.internalAutoProxyCreator
Before Advice processing
Playing guitar :LakeWood
Executing :com.example.demo.aspect.GrammyGuitarist playGuitar
Get Guitar LakeWood
Start to play guitar
zzZZ!!!!
在 Spring Boot 中,默認啟用 CGLIB 強制。 檢查這個問題以獲得更好的理解
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.