I am trying to use test database for my application. I am using MyBatis.
I have 2 environments configured in MyBatis configuration file. I have set property like so in my ResourceConfig subclass.
property("Env","development");
I am able to get this value i,e development in my Resource like fallows
#Context Application app;// this is instance variable
System.out.println(app.getProperties().get("Env"));// this statement in resource method
I have 3 layers Controller(i,e Resource class), Action Layer and DAO and DMO mapper layer.
But the above 2 statements which are working in resource class is not working in DAO class. I am getting a NullPointerException at System.out.println Line
Now I have to get the environment in Resource and pass it to further layers. Is there a better way to do this.
All I want is to choose test database for testing and development database for development
Most likely because you are just trying to instantiate the DAO youself
#Path("boogers")
class Resource {
Dao dao = new Dao()
}
That's not going to work. The Dao needs to go through Jersey's injection system. The resource works because it goes through the injection system. If you want to do the same for your Dao, then you need to inject it and let it go through the DI system. That way the system will inject it with required dependencies before injecting it into the resource
#Path("boogers")
class Resource {
#Inject
Dao dao;
}
Here, you don't instantiate it, You let the DI system create it and inject it. To make it work, you need to make the Dao injectable.
class AppConfig extends ResourceConfig {
public AppConfig() {
register(new AbstractBinder() {
#Override
protected void configure() {
bindAsContract(Dao.class);
}
});
}
}
Here you're binding the Dao class to the injection system, so that whenever it sees #Inject Dao, it will be able to grab/create it and inject it.
Related
There are two application. Main Application and Utility Application where utility Application is packaged as jar in Main application. Both are spring boot application.
In utility application I create an object of a class A which is present in Main Application using reflection API.
Class A has one Autowired instance variable defined in it. Issue is when Utility Application tried to run some method one the same class A object, then that autowired variable results in null.
I guess, since I am creating the object manually that is why it is not managed by Spring.
Now my question is how can provide this object to spring context so that any Autowiring happening inside the class A actually gets autowired.
Below is the code samples
under Main Application
package m.main.application.A;
class A implements Action{ //Action interface coming from utility application
#Autowired
private Calculator calculator
#override
public void execute(){
calculator.add(5+2); //Here calculator is null. Autowire is not working
}
}
Utility Application packaged as Jar in Main Application
Class Util{
public createObjectAndRun(){
Class<?> class = Class.forName("com.main.application.A");
Action newObject= (Action) class.getConstructor().newInstance();
//executing execute
newObjects.execute(); //This fails as calculator is not autowired
}
}
I want to know if there is a way we can make calculator gets autowired properly.
Your class A is not annotated with any spring stereotype (#Service, #Component, etc), so it's not a spring managed bean. So one way you could achieve this would be making it a spring bean (using a stereotype) and get it through ApplicationContext's method getBean on your Util class.
I have a custom Stored Procedure class which is extending jdbc.StoredProcedure but I have annotated this class with Spring #Component to bring this class bean into Spring context.
Why I am doing this?
I wanted to add spring-retry on execute method which will work only on spring components
I wanted to reused the compiled StoredProcedure instead of creating a new object and recompiling every time, in this way I can reuse the compiled StoredProcedure every time.
anything wrong with this kind of implementation?
are there any issues we may see with this Spring component based StoredProcedure?
Ex:
#Component
public class ExampleStoredProcedure extends StoredProcedure {
#Autowired
private DataSource dataSource;
#Postconstruct
public void init() {
super.setDataSource(dataSource);
setSql("stored_procedure_name");
//TODO declare parameters
compile();
}
public void execute(){
//Todo set all parameters to ParameterSource
super.execute(parameterSource);
}
}
Try implementing a layered application architecture where you annotate your services with spring retry like this example:
https://dzone.com/articles/spring-retry-way-to-handle-failures
These service methods can define transaction boundaries and call your data persistence layers methods that could be based on spring data's standardized ways to call stored procedures and manage your database connections etc.
See for more info on Spring and architecture for example this brief introduction:
https://www.petrikainulainen.net/software-development/design/understanding-spring-web-application-architecture-the-classic-way/
I know that there are questions similar to this one, but none of them have helped me. I'm following along this tutorial, and the part I can't wrap my mind around is:
#SpringBootApplication
public class Application {
private static final Logger log =
LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
#Bean
public CommandLineRunner demo(CustomerRepository repository) {
return (args) -> {
// save a couple of customers
...
// more lines, etc...
What I don't understand is where the repository passed into demo comes from. I know that the Autowired annotation can do something like that, but it isn't used at all here.
The more specific reason I ask is because I'm trying to adapt what they do here to an application I'm working on. I have a class, separate from all of the persistence/repository stuff, and I want to call repository methods like save and findAll. The issue is that the repository is an interface, so I can't instantiate an object of it to call the methods. So do I have to make a new class that implements the interface and create an object of that? Or is there an easier way using annotations?
When creating a #Bean, adding the repository in the parameters of the bean is enough to wire the repos in your bean. This works pretty much like adding #Autowired annotation inside a class that is annotated as #Component or something similar.
Spring works mostly with interface, since that is simplier to wire vs wiring concrete classes.
Can you try #Repository before the declaration of class? Worked for me in a Spring MVC structure.
#Repository
public class EntityDAOImpl implements EntityDAO{
...
}
The thing to wrap your head around is a Spring Boot application at startup time aims to resolve its dependancy tree. This means discovering and instantiating Beans that the application defines, and those are classes annotated with #Service, #Repository, etc.
This means the default constructor (or the one marked with #Autowire) of all beans is invoked, and after all beans have been constructed the application starts to run.
Where the #Bean annotation comes into play is if you have a bean which does not know the values of it's constructor parameters at compile time (e.g. if you want to wire in a "started at" timestamp): then you would define a class with an #Configuration annotation on it, and expose an #Bean method in it, which would return your bean and have parameters that are the beans dependencies. In it you would invoke the beans constructor and return the bean.
Now, if you want a certain method of some class to be invoked after the application is resolved, you can implement the CommandLineRunner interface, or you can annotate a method with #PostConstruct.
Some useful links / references:
https://docs.spring.io/spring-javaconfig/docs/1.0.0.m3/reference/html/creating-bean-definitions.html
https://www.baeldung.com/spring-inject-prototype-bean-into-singleton
Running code after Spring Boot starts
Execute method on startup in Spring
My goal in this entire endeavor is to try and inject a data source into a resource that can change at runtime. I am trying to avoid having to bloat the logic inside my resource if at all possible.
This is a legacy application with Jersey 1.19.1 using Spring 4.1.9.RELEASE (spring-aop, spring-beans, spring-context, spring-core, spring-expression, spring-web)
So here is my example resource:
#Path("/test)
public class TestResource {
public TestResource(){
System.out.println("Constructor Hit");
}
}
If I run hit this resource I get the following output
...request...
Constructor Hit
...request...
Constructor hit
So, the resource is created everytime there is a request, great!
Now, I want to use spring to inject a bean into this resource, so I get the following class.
#Path("/test)
#Component
public class TestResource {
#Inject
public TestResource(MyBean test){
System.out.println("Constructor Hit");
}
}
Now I get the following output
Constructor hit
...request...
...request...
The resource is only created once (I'm guessing at Spring application creation time).
Is there a way to fix this? I believe it is because I annotate with #Component but I can't seem to get the injection part without that.
Spring's default scope is singleton. when you call prototype class in singleton, spring DI inject prototype class just once at instantiate time.
read this issue if you want the singleton bean get a new instance of the prototype bean at runtime.
I have a singleton class and one its private members is ServletContext object.
I made it singleton to remove spring dependency since I am trying to write in pure java code.
public class Utils {
private static Utils utils = null;
public Utils() {
// Exists only to defeat instantiation.
}
public synchronized static Utils getInstance() {
if (utils == null) {
utils = new Utils();
}
return utils;
}
#Autowired
private ServletContext servletContext;
public void makeUtils() {
// output csv path
String outputFile = servletContext.getRealPath("/util");
}
}
But here servletContext will be null because I am creating the object of Utils class wherever I needed manually. Not by using #Autowired. So spring is not injecting the dependency. How can I solve this.
#Autowired is a spring annotation.
If you want something to happen in response to that annotation, then you need to use spring. If you want to remove the dependency on spring, then you can't use Autowired. You need to pick one - are you depending on spring for your wiring, or not?
Some solutions you could follow:
Using Spring
Make Utils a spring bean and inject it
Put Utils into your spring context (bean factory) and then inject it (using #Autowired, or another wiring strategy) into every other class that wants to use it.
Make Utils a spring bean and look it up.
There's really not much reason to do it this way, but if you want, you can get access to your spring bean factory (probably via the ApplicationContext) and lookup a bean by type using BeanFactory.getBean(Class<T>)
Use Spring to autowire an existing Utils object
Again, there's not many good reasons to do this, but if you have an instance of AutowireCapableBeanFactory (which you can get via ApplicationContext) then you can call autowireBean(Object existingBean) to get spring to wire up your #Autowired fields.
Note: My method/class references are from Spring 3.2 because it's what's open in my IDE right now. You may need to make adjustments if you have a different spring version)
Without Spring
Instantiate Utils within a Servlet (or Listener)
Create a configure method on Utils that takes the ServletContext.
Inside a Servlet (or a ServletContextListener) call that configure method to set the servletContext field on Utils.
Store a static global ServletContext
Create an object like ServletContextHolder that has a static field on which you can store the ServletContext
Inside a Servlet (or a ServletContextListener) call the setContext method on that holder set the servletContext field.
Inside Utils call ServletContextHolder.getContext()