Spring aop 破坏了原始代码?启用方面时,自动装配 bean 的字段变为空

Spring aop breaks original code? The field of the autowired bean becomes null when the aspect is enabled

启用方面后,BeanB中的@Autowired bean成为代理,name字段为空。为什么?如果我希望原代码能正常工作,我应该怎么做?

代码如下:

public class BeanA
{

    @Value("jami")
    //public String name;
    String name; //package visiblity


}

public class BeanB
{

    @Autowired
    private BeanA beanA;


    public void noLongerWorks()
    {
        System.out.println(beanA.name);
    }
}

public class Main
{

    public static void main(String[] args)
    {

        String[] configs = {"applicationContext.xml", "applicationContext-aop.xml"};//prints null
//      String[] configs = {"applicationContext.xml"};//prints jami
        ApplicationContext ctx = new ClassPathXmlApplicationContext(configs);


        BeanB beanB = ctx.getBean(BeanB.class);
        beanB.noLongerWorks();

    }
}

------------ applicationContext.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"
       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">


    <context:annotation-config />
    <bean class="aop.pack1.BeanA" />
    <bean class="aop.pack1.BeanB" />


</beans>

------ applicationContext-aop.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: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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <aop:aspectj-autoproxy />
    <bean class="aop.pack1.TestAspect" />


</beans>

@Aspect
public class TestAspect
{


    @Pointcut("target(aop.pack1.BeanA)")
    public void pointcut() {}


    @Before("pointcut()")
    public void advice()
    {
        System.err.println("___________advice__________");
    }
}

编辑: 我想出了一个可能的解决方案。但是好像不是很干净。有什么优雅的方法吗?不更改现有代码? 我找到的解决方案:

is to make all the fields in BeanA private, and only access them via getter setters.
This approach, however, requires a lot of modification of the original code (e.g. the BeanA class). 

你已经解决了这个问题,但是,我想分享这个 article 我看到它列出了 Spring AOP 可以做什么和不能做什么。

你的情况

  1. Since it uses proxy-based AOP, only method-level advising is supported; it does not support field-level interception So join-points can be at method level not at field level in a class.

  2. Only methods with public visibility will be advised: Methods with private, protected, or default visibility will not be advised.

只是一个建议,我认为创建具有 private or protected 可见性的字段并提供适当的 getter 和 setter 来访问它们也是一个很好的 OOP 实践。

这些 SO Q/A 可能有用

spring singleton bean fields are not populated