Loading manually created object to spring context - spring

I have an object created using a new operator. Is there a way, in Spring, to load this object in the Spring application context?
I did some research but could not find a working solution. Thanks in advance.

If you are creating an object after Spring application has started and you want to register it as bean with spring, you can do it. ie. run time only you will know how it will be created or that object is created by a external framework you don't have control over. I just can't remember the frameworks, there are frameworks that used this facility.
//Get hold of application context, you can autowire it
ConfigurableApplicationContext context;
ServiceX servicex = //This object was created outside spring framework.
//Register it with spring
context.getBeanFactory().registerSingleton("servicex", servicex);
//Above bean is now available as part of spring application context.

You can use Spring's #Configuration class and define #Bean method in there. In that method, create your custom new object and make sure you return that object.
#Bean
public YourType methodName() {
//code here..
return new YourType();
}
Put this into your #Configuration class and object returned by return new YourType(); will be registered into your Spring Context.

Related

Is there some way to get access to Spring bean from Spock extension?

There is an example what I want to do.
The service client is a Spring bean, which is retrieving from external configuration class and should be called from Spock extension.
class ServiceCleintExtension implements IGlobalExtension {
#Autowired
ServiceCLient client
#Override
void start() {
client.execute()
}
...
}
UPD:
I've found a solution by using Spring TestExecutionListener and custom static "container" for SpecInfo/FeatureInfo.
No that is not possible, IGlobalExtension are initialized and manged by Spock. Furthermore, they are singletons which doesn't mesh well with multiple possible Spring contexts.
If you just want to call a method on an injected bean during setup, then I'd suggest to use an annotation based extension. Look at the builtin AutoCleanup extension for reference.

Spring in a JavaFX application - how to property handle controller as dependency?

I have a JavaFX application that uses spring boot, exactly as described in this blog post:
http://www.greggbolinger.com/let-spring-be-your-javafx-controller-factory/
I am using the FXML loader overriding the controller factory to use spring.
The problem is that Spring loads the controller class marked as #Component on application start or later if marked with #Lazy, but keeps the bean in memory.
If I open a Stage, modify the data, close the stage and open it again, the data is still there (because the controller was kept by spring). It also gets in the way if I open two of the same Stage (window). It shares the same controller, so if I modify one, the other modifies too, and this is not the desired behavior.
How to I properly handle JavaFX controllers with spring?
Thanks!
Mark the controller as having prototype scope, so that a new instance is created on each request:
#Component
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Controller {
// ...
}

Invoking proxied DAO methods from Spring stand alone client :- could not initialize proxy - no Session

I have a third party jar in my class path which has some services and DAO's developed on top of Spring 2.0.6 and Hibernate3.2.6. I need to call some of the services and daos.
Using ClassPathXmlApplicationContext I'm able to load the application context and able to access the services and daos. Both the service and dao are following ProxyFactoryBean pattern.
Problem comes when I'm accessing a DAO which has some single valued associations.When I'm accessing associated entity I'm getting lazy initialization problem.
To solve this problem:- If it is in my own application JAR I'll be able to change the fetch type into join or in DAOImpl method I could use Hibernate.initialize().
Is there a way to avoid this problem from the stand alone code itself? Or any other way to solve this issue without modifying applicationContext.xml and DAOImpl
You need to put the caller method into one single transaction.
If you have Spring transactional environment, you can put the call of the DAO services/repositories in your own service/method which is marked as #Transactional, or if transaction support is not enabled, but you still have spring support in your application, you can just use TransactionTemplate directly, provided by spring
#Autowire
private PlatformTransactionManager txManager;
TransactionTemplate template = new TransactionTemplate(this.txManager);
template.execute( new TransactionCallback<Object>(){
public void doInTransaction(TransactionStatus status){
// work done here will be wrapped by a transaction and committed.
// status.setRollbackOnly(true) is called or an exception is thrown
}
});
Otherwise you have manually handle transactionality by your own , depending on the technologies your app is using.

How to inject a JSF bean into a spring bean

I'm working on a legacy JSF application which we are slowly porting over to Spring MVC. We are using Spring Security to control login information. After logging the user in, the JSF pages globally instantiate a session scoped bean that is used everywhere. I'd like to change the application so that we can go to a page that was developed with Spring MVC first.
One approach I tried was to convert the bean into a spring bean and have it injected into JSF, but unfortunately that turned out to require a lot of changes to the bean to make it possible. One possible hack I thought of is to add a special redirecting JSF page to initialize the JSF beans before sending the user to the Spring MVC page. That seems like quite a bit of a hack though so I'm looking for another solution.
Is there some other way that I can force the session scoped bean to be initialized before I go to my Spring pages so that I can just pull the bean out of session?
If you are using Spring MVC, you can make your "bean" a Model Attribute, then have it auto-loaded into session using a combination of annotations on the Controller, handler methods, and a method that creates an instance of your bean. Your controller would look something like this:
#Controller
#SessionAttributes({"myBean"})
#RequestMapping("/myPath")
public class MyController {
#RequestMapping("/myPath2")
public String myHandler(#ModelAttribute("myBean") MyBean myBean) {
// ...do stuff, return view
}
#ModelAttribute("myBean")
MyBean createMyBean() {
// Create and init an instance
return new MyBean();
}
}
You will get a MyBean magically created for you whenever there isn't one, and any time you update the Model (or ModelAndView) with "myBean", it will also get magically added to the Session.

How can I instantiate an injected class (using Spring) before logback configuration

I am using spring to inject a class into my PropertyDefiner implementation which will be used to help set up some properties within the logback.xml file (through dynamic property loading).
I'd love to get this class loaded and instantiated before logback is configured. Any thoughts on how to do this?
If you're using annotations in Spring, it's convenient to do this by marking the class (i.e. the dependency) you'll be injecting as #Component and then using #Autowired in your PropertyDefiner implementation. This ensures that the first class will be instantiated first. http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s12.html
Any other initialization you require could be achieved using instance initializer blocks http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
I do not know if this can be done elegantly at present time (2012-07). However, support for injection has been requested in LOGBACK-719.
If your bean factory implements AutowireCapableBeanFactory, given the Spring Applicaton context, you could invoke autowireBean(Object existingBean) to autowire the bean. Here is a tentative implementation:
class Your.PropertyDefiner implements PropertyDefiner, LifeCycle {
#Autowired
#Qualifier("myKey")
String myKey;
public void start() {
ApplicationContext appContext = ... somehow get the spring app context
AutowireCapableBeanFactory factory = appContext.getAutowireCapableBeanFactory();
factory.autowireBean(this); // declare victory
}
}
The start() method will be invoked only if your PropertyDefiner implements the LifeCycle interface. Moreover, you need logback version 1.0.7 or later. Earlier versions do not invoke start().
My solution resulted in not implementing a PropertyDefiner. The original question became an issue of not having the application context from spring to set the dynamic properties. I'm not sure why, but code in a later listener (after the Spring listeners) would get called (invoking the LoggerFactory call) before the application context was available. I tried a number of things, until I starting looking at a different approach.
Instead of using dynamic properties I created a listener (called on server startup) which then programmatically sets up my appender with the properties I want (through the createAdminNotifyAppender).
#Override
public void contextInitialized(ServletContextEvent arg0)
{
//Set up the property reader to pull the correct properties
ServletContext context = arg0.getServletContext();
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(context);
propReader = (AppConfigPropertiesReader)appContext.getBean("propertySourcesPlaceholder");
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
createAdminNotifyAppender(lc, propReader);
}
The createAdminNotify method simply sets up an appender and adds it to the logging context. (if you're really interested, you can see that method's implementation on this thread).
Now I have a separate and modular listener that I can add to other apps that are using logback, but possibly with different properties. The properties are pulled from a database and can also vary by environment.

Resources