【问题标题】:Can programatically created object can access spring context via annotations?以编程方式创建的对象可以通过注释访问弹簧上下文吗?
【发布时间】:2014-04-17 14:26:57
【问题描述】:

假设我有以下 spring.xml(SomeBean 由 spring 管理)

<bean id="some_bean" class="SomeBean" />

和类(这个不是托管的)

public class MyClass {
    @<some magic or something else?>
    private SomeBean sb;
}

和我的主要

public class Main {
    public static void main(String[] args) {
        new MyClass().getSB();
    }
}

如何通过创建新类(使用 new 关键字)MyClass 实例来访问 id="some_bean" 的 bean?

【问题讨论】:

  • 查看 AspectJ。如果您无权访问 ApplicationContext,否则这是不可能的。
  • 你必须让 MyClass 对 Spring 可用。但是你可以在运行时设置:stackoverflow.com/questions/15328904/…

标签: java spring spring-mvc


【解决方案1】:

如果您使用 Spring AOP 并使用 @Configurable 注释,您可以将 some_bean 直接注入到您预先存在的 MyClass 中:

@Configurable
public class MyClass {
    @Autowired
    private SomeBean sb;
}

以上代码将按类型注入。如果你碰巧有多个SomeBeans,那么按名字注入:

@Configurable
public class MyClass {
        @Autowired
        @Qualifier("some_bean")
        private SomeBean sb;
    }

【讨论】:

  • 好吧,我试过了。但是什么也没发生(NPE 除外)。我尝试挖掘一下以找到一些配置,但没有找到任何对第一次使用AspectJ 的人有用的东西。它说我可能需要 3 个罐子(aspectjrtaspectjtoolsaspectjweaver)所以我将它们添加到依赖项中。还尝试添加类似&lt;context:spring-configured/&gt; 的内容,但也没有真正发生任何事情。我错过了什么?
  • 好的。我设法在加载时使用 -javaagent:path_to_agent.jar 解决它。
【解决方案2】:

如果您可以访问应用程序上下文,那么您可以将其获取为:

    public class MyClass {
        @Autowire
        private SomeBean sb;
    }

    public class Main {
        public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        MyClass myClass = new MyClass();
        ctx.getAutowireCapableBeanFactory().autowireBeanProperties(myClass, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
    }

【讨论】:

  • 相当丑陋的方式,AspectJ 看起来不错,但如果我无法设置它,我可能会这样做。谢谢。
【解决方案3】:

如果您不喜欢 AOP / AspectJ,另一种选择是创建一个 MyClassFactory bean,该 bean 负责创建 MyClass 的新实例,并向其中注入 SomeBean 引用(通过构造函数注入或方法注射),例如

@Service
public class MyClassFactory {
    @Autowired
    private SomeBean sb;

    public MyClass createMyClassWithSomeBean() {
        MyClass myClass = new MyClass();
        myClass.setSomeBean(sb);
        return myClass;
    }
}

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
        MyClassFactory factory = ctx.getBean(MyClassFactory.class);
        MyClass myClass = factory.createMyClassWithSomeBean();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 2022-01-15
    • 1970-01-01
    相关资源
    最近更新 更多