1

I'm quite new to spring (switching from PHP to Java).

In my code I have a java.lang.reflect.Method objects and I need to instantiate it's class with all it's dependencies.

Normally I'd use @Autowired annotation in my code, but it's not possible because my code gets different Method objects, not specific classes.

Question is - how to get a class instance from dependency container without using annotations and having just class name?

In php i used libraries which gave me access to container and I could just get DI services by it's class name just like:

$this->container->get('My\Class\Name'); 

In spring I tried:

@Autowired private ApplicationContext context; void myMethod(Method method){ this.context.getBean(method.getClass()); 

and

this.context.getBean(method.getClass().getName()); 

and that was resulting in NullPointerException.

EDIT Thanks for quick replys,

I tried using

context.getBean(method.getDeclaringClass()); 

and

context.getBean(method.getDeclaringClass().getSimpleName()); 

And it both resulted in NullPointerException as well.

Actually it's okay for my needs to get that class by class or by name. I'm trying to write my own command bus for CQRS. Let me show you some code:

Handler:

public class SimpleCommandBus implements CommandBus { @Autowired private ApplicationContext context; private Map<Class, Method> registry = new HashMap<>(); @Override public void register(Class c, Method o) { registry.put(c, o); } @Override public void dispatch(Object command) { if (!registry.containsKey(command.getClass())) { throw new CommandDispatchException(String.format("Handler for command %s was not defined.", command)); } Method method = registry.get(command.getClass()); Object handler = context.getBean(method.getDeclaringClass().getSimpleName());//line causing exception 

Service class:

@Service public class TestHandler { public void handle(TestCommand command){ System.err.println(command.getId()); } } 

Calling command bus:

 Method method = TestHandler.class.getMethod("handle", TestCommand.class); TestCommand command = new TestCommand("Test command"); commandBus.register(TestCommand.class, method); commandBus.dispatch(command); 

2 Answers 2

4

Use java.lang.reflect.Method.getDeclaringClass() to find in which class the given method is declared. method.getClass() will return the type of method object which is java.lang.reflect.Method.

@Autowired AplicationContext ctx; ... Object bean = ctx.getBean(method.getDeclaringClass()); 
Sign up to request clarification or add additional context in comments.

9 Comments

That may also work but the question was "get ... by its name"
Unfortunately that doesn't work. I've added some code in question edit to clarify
@MateuszWu Spring will produce proxies for the beans e.g. to support the @Transactional. What does method.getDeclaringClass().getSimpleName() return?
System.err.println(method.getDeclaringClass().getSimpleName()); returns "TestHandler" @KarolDowbecki
In addition - i also checked if i can autowire that service (TestHandler) to make sure that spring DI can see it and it works perfectly.
|
1

In Spring the default name is the simple name.

Plus as in Karols answer you must use getDeclaringClass() to get the class of the class with the method.

So you must call

this.context.getBean(method.getDeclaringClass().getSimpleName()); 

2 Comments

Unfortunately that doesn't work. I've added some code in question edit to clarify
Can you please add the stacktrace of the exception you get?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.