Spring - how to debug to find specific use of spring's auto-wiring or a request parameter? - spring

Spring is auto-wiring in a request parameter - let's call it "bob".
I don't know where nor how it is doing this, so I cannot debug it. What spring specific code (using intellij, so I can at lest set a conditional) would be appropriate to find where the auto-wiring of the request parameter is happening, so I can work out what the system is doing?

I think I understood the question, so I will try to answer it as best as I can.
You are facing a dilemma of choosing between managing your instances, or letting Spring manage them. If you let Spring manage dependency injection, you will often face situations where you wish you had more fine control over the beans lifecycle.
By default, Spring beans are "singletons", which means that only one
instance of that object will be created, and every class that demands
a dependency injection of that object will receive the same instance.
The first step on beans lifecycle is its construction. You can setup a breakpoint to catch that moment on any method annotated with #PostConstruct. This article describes the need of running some code on bean initialization, and how it is solved by this annotation. For example:
public class AnyBean {
#PostConstruct
public void init(){
// any code or breakpoints inserted here will
// be run whenever an instance of this bean is created.
// if a singleton bean, only one instance is created and,
// only one #PostConstruct will be called.
// If a bean is a prototype bean, a new instance will be created
// for every dependency injection, and hence one #PostConstruct
// will be called for each.
}
}

Related

How To Execute method before #PostConstruct work??

I am Trying to update DB Schema whenever application version updated.
Some People said It is not a good Function but I wanna try whether I use it or not.
I Succeed Update schema when application booted.
but I have to change the timing that schema updated. and It is between after Bean object DI finished and before #PostConstruct work.
is it impossible, just before #PostConstruct work whether DI is finished or not.
how can I do this?
PS. I have known flyway work similar function compared I am making. but I want to make similar thing by my self.
When spring bean gets initialized, spring guarantees that all the properties will be injected (by means of applying constructor injection, setter injection or field injection)
So First of all spring calls bean's constructor
Then (if the fields are not set yet) it tries to inject fields
And only after that, it calls #PostConstruct
So you should be able to access the database from the post-construct method of the bean.

How to instantiate Spring bean with custom scope and #Autowired dependencies?

In our project, we use Spring request scoped beans. Now we've a requirement to support async requests and request scoped beans don't work for child threads. I'm aware of RequestContextFilter and it's "support" for async but it appears that RequestContextFilter expects the main thread to wait for the child threads to finish, which isn't the case for us. Our main thread immediately returns after spawning new threads using #Async annotation and DispatcherServlet clears out the RequestContextHolder. Thus when the child threads get to the point where they need a request scoped bean, #Autowired fails.
I'm also aware of SimpleThreadScope but it doesn't clean up thread-local attributes and in a thread-pooling situation, is not only dangerous to use but downright useless.
What I need is a custom scope. So far, I've found 3 useful examples but all of them fall short in that the beans they instantiate as part of the custom scope are plain POJOs without any dependencies. Needless to say that's non-existent in a real life application. Can anyone suggest a way to instantiate custom scoped beans that have #Autowired dependencies on beans from other scopes?
What I found so far:
https://github.com/spring-by-example/spring-by-example/tree/master/modules/sbe-thread-scope/src/main/java/org/springbyexample/bean/scope/thread
https://github.com/billkoch/spring-async-mdc
Spring Bean Custom Scope JMS
Continuing the discussion from the other question's answer here...
See the Spring Documentation about scoped beans as dependencies.
.
I'm referring to the <aop:scoped-proxy/> which is what the link points to. Each time the autowired field is referenced, your custom scope's get() method is called to lookup the instance based on some criteria.
.
I understand I can look up the dependencies (though unsure how, a scope isn't a bean, perhaps I need to pass application context during instantiation?). What I don't understand is how to inject those dependencies into my bean if those're marked #Autowired? Or are you saying the custom scoped bean shouldn't have #Autowired dependencies?
It works automatically; Spring injects a proxy for the bean and the scope.get() is invoked on every method call on that bean, returning the specific instance you want in the context of the current invocation.
Take a look at the AbstractRequestAttributesScope to see how it works (in that case, gets the instance from the HTTP Request and, if it doesn't exist, creates it).
So, your code calls foo() on the proxy; the framework calls the scope to get the desired instance and then calls foo() on that instance.
The exposed methods you wish to call must either be on an interface or not declared final.

Spring fallback bean implementation

I'm currently trying to configure Spring Boot (using Java Annotations and ComponentScan) for the following scenario:
Scenario
There's an interface MyService.
I want to provide a default implementation for MyService, let's call it MyDefaultService.
If the component scan detects no other implementation for MyService, Spring should instantiate MyDefaultService as a "fallback".
If there is a different implementation of MyService present, let's say MyCustomService, then that bean should always take precedence over MyDefaultService when autowiring a dependency to MyService. In that regard, MyDefaultService should be recessive (as opposed to #Primary).
Ideally, there should not need to be an additional annotation on MyCustomService to have it "override" MyDefaultService.
Ideally, no explicitly implemented factories or factory methods should be required.
Question
The question is: how do I need to annotate the MyDefaultService class in order to achieve this?
What I tried so far to solve the problem
Annotating MyDefaultService with #ConditionalOnMissingBean(MyService.class). Didn't work because MyDefaultService is never used, even if there is no other implementation of MyService.
There is an annotation called #Primarythat solves the problem. However, it needs to reside on MyCustomService, a class that I try to keep free of additional annotations. Essentially, I need the inverse annotation of #Primary on MyDefaultService. However, I couldn't find such an annotation.
Concrete use case
I am developing a service layer in one project, and a different project will implement a web UI layer on top of it. The UI project has a dependency to the service layer project. However, for certain functionalities implemented at the service layer, I need to know which user is currently logged in at the web context. So I have to define a service interface for that in the service layer project, such that it can be implemented by the UI project. However, for testing purposes in the service-layer project, I need a default implementation of that interface. Also, in case that the UI project team forgets to implement this interface, the app should not crash, but instead instantiate the fallback bean and issue a warning.
Thanks & kind regards,
Alan
I suggest writing an implementation of FactoryBean to do this. Your FactoryBean would scan the bean factory looking for beans that implement MyService, and if it finds one it returns that bean from getObject. If it doesn't, then it can instantiate MyDefaultService directly and return that. Your factory bean then gets annotated with #Primary.
So pieces like this (pseudo-code):
public class MyServiceFactory implements FactoryBean<MyService> {
ListableBeanFactory beanFactory;
public MyService getObject() {
Map beans = beanFactory.getBeansOfType(MyService.class)
if (beans.isEmpty())
return new MyDefaultService(); // plus args, obviously
else
return get_some_bean_from_the_map
}
}
and then
#Primary
#Bean
public MyServiceFactory MyServiceFactory() {
return new MyServiceFactory();
}
Spring will automatically handle the factory bean (i.e. it will make the MyService object available as a bean for injection like normal.
This solution doesn't require any special magic, and it's fairly obvious how it works. You can also handle errant cases such as multiple MyService beans being declared.

injecting spring beans into non-singleton classes

is it possible to inject spring beans into a polling filter class (FClass) controlled by a scheduler job?
i don't quite understand how singleton applies here.
i understand spring beans are singleton so in order to inject the spring beans into class FClass. i need to define FClass as a bean and add the DI as property etc..
so how do i know if FClass should be a singleton? i assume only classes that are singletons can be created and beans and have DI done to them.
my problem is :
i need to be able to inject my facade bean xfacade into FClass. x_facacde handles the dao object. it has Y_dao and a Z_hibernate session beans injected as DI.
when i tried to create a spring bean of StatusPollingFilter (FClass) and injected the facade bean - i got a null and the setter is never called for the injection in debug mode.
the problem:
i'm thought it might be something to do with the thread / scheduler nature of StatusPollingFilter, and since spring beans are singletons it might not work due to that.
i'm thinking of creating a factory for the StatusPollingFilter (FClass). but need to know if this is correct thing and i'm on right track before i do too much work and realize even that doesn't work as the problem might be somewhere else. ideally i just want to update a table in the easiest possible way. but i have to use hibernate as the DAO exists but hibernate is configured using
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
with /hibernate/TopoObject.hbm.xml
files.
so no matter how i try this i always get null pointer exception on session or injected facade bean.
reading some of the QA's here seems like because StatusPollingFilter is instantiated using the scheduler and not spring it cant be aware of the DI beans. so would the above factory pattern help here.
I may have an additional problem but i'll cross that bridge when i come to it. but just to mention briefly, in case anyone is aware of issues that i might hit ... not sure what / how the scheduler would invoke the factory for an instance as its all controlled by 3rd party api - which invokes a StatusPollingFilter but i'm assuming if i pass in the factory as the class and parameter it would find its way through... but initial part is the main question. please ignore the latter waffle. thanks in advance.
Actually :
i assume only classes that are singletons can be created
is where you are wrong.
A bean is just a class that you let spring instantiate. By default, they are created as singleton but you can specify the scope on your bean using the attribute scope (quite surprisingly). The value you can specify are those specified in the documentation here
So one thing you have to be careful with is the injection of beans scoped as prototype or request into singletons.
having read more - i have come across the ans.
because the StatusPollingFilter object is under control of scheduler (i knew that scheduler had something to do with it) then it is unaware of the spring beans which is why i keep getting null when i try injecting the bean.
i created a class:
ApplicationContextProvider implements ApplicationContextAware
added static access
private static ApplicationContext appContext;
did a setter for it :
public void setApplicationContext(ApplicationContext context)
{
appContext = context;
}
and added
public static Object getBean(String beanName) throws BeansException
{
return appContext.getBean(beanName);
}
used in code as :
EvoTAMDAOFacade evoDao = (EvoTAMDAOFacade) ApplicationContextProvider.getBean("evoDaoFacade");
i now have access to the facade bean and all injected beans into facade.
i still have an issue with hibernate session but thats prob due to some other issue.
pt here is i don't have access to the bean as its not in control of the spring container so i needed to somehow get it , probably could have done it via the factory method but why mess around when there a simpler way.
thanks for help by anyone who may have posted or tried to understand my problem.

How does spring self injection works with #Resource?

This is a question to understand spring internals. There are a couple of workarounds suggested for self injection of a bean in spring because #Autowired doesn't work. Here are few threads. I would like to know the reason why and how does self injection work technically with #Resource annotation?
#Service(value = "someService")
public class UserService implements Service{
#Resource(name = "someService")
private Service self;
}
Any links to the spring source code would be appreciated. Thanks.
From another thread I got a response which seems fairly ok. Basically it states that spring specially adds defensive checks for handling #Autowired beans but #Resource beans bypass it and hence it works.
I don't know how exactly spring handles it, but here are a few options (the CDI specification uses these for example):
incomplete instances. When beans are instantiated and put in the context, their status is set as 'incomplete' - that is, their instance exists but their dependencies are not injected. Thus, first beans are instantiated, put in the context, and on the next stage their dependencies are injected. This makes the above case trivial - the container first create the instance and then, for each injection point, gets the desired bean from the context - itself, in this case
proxies. A proxy is created for each bean, so that it has beans without actually having instantiated the beans. It creates the proxies (by interface/concrete class), injects them into one another, and passes proxies around when needed. Finally each proxy gets its actual bean. This is perhaps not the case above, because this is used by CDI to handle circular constructor injection.

Resources