0

Let's say I have following spring.xml (SomeBean is managed by spring)

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

and class (this one is not managed)

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

and my main

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

How to make that by creation of new class (using new keyword) MyClass instance have access to bean with id="some_bean"?

abc
  • 2,371
  • 3
  • 25
  • 36
  • 1
    Look into AspectJ. It's otherwise impossible if you don't have access to the ApplicationContext. – Sotirios Delimanolis Apr 17 '14 at 14:39
  • You have to make MyClass available to Spring. But you can set it at runtime: http://stackoverflow.com/questions/15328904/dynamically-declare-beans-at-runtime-in-spring – zenbeni Apr 17 '14 at 14:40

3 Answers3

1

You can inject some_bean directly to your pre-existing MyClass if you employ Spring AOP and annotate it with @Configurable:

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

The above code will inject by Type. If you happen to have more than one SomeBeans, then inject by name:

@Configurable
public class MyClass {
        @Autowired
        @Qualifier("some_bean")
        private SomeBean sb;
    }
dimitrisli
  • 20,895
  • 12
  • 59
  • 63
  • Well I tried that. But nothings happen (except NPE). I try dig a little bit to find maybe some configuration, but not find anything what would be useful for some using `AspectJ` for 1st time. It says that I might need 3 jars (`aspectjrt`, `aspectjtools` and `aspectjweaver`) so i add them into dependency. Also tried add something like `` but nothing really happens as well. What I'm missing? – abc Apr 17 '14 at 16:18
  • Ok. I manage to solve it using -javaagent:path_to_agent.jar at load time. – abc Apr 17 '14 at 16:59
1

If you have access to application context then you can get it as:

    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);
    }
Prasad
  • 3,785
  • 2
  • 14
  • 23
  • Quite ugly way, AspectJ one looks nice, but if I wouldn't manage to set that thing up I probably do it that way. Thanks. – abc Apr 17 '14 at 16:19
0

One alternative if you don't like AOP / AspectJ is to create a MyClassFactory bean that is responsible for creating new instances of MyClass, and inject a SomeBean reference into them (either by constructor injection or method injection), e.g.

@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();
    }
}
matsev
  • 32,104
  • 16
  • 121
  • 156