Call a #Autowired Repository from a static context - java

I have a createEntity method that is static, because i need to call it from other entities, inside this method, i need to call a repository, but logically i can't do it because it's non static.
public static Client createEntity(EntityManager em) {
default_operation = operationRepository.save(OperationResource.createEntity(em));
}
I wouldn't ask if i hadn't my head blown away by this, i tried to use #Autowired constructors as other solution suggested but this won't work for a repository.
If anyone has an idea, or a workaround, i would appreciate it!

Using static methods causes problems (not only in Spring). One of the reasons is that the autowired properties of a class are not available in a static context. They are only injected during certain stages of Spring's lifecycle.
You should declare the class that contains the createEntity method as a Spring bean (for example with #Component). Then you can inject this bean (with #Autowired) in all other classes that need to call createEntity.

I DO NOT recommend this, but because of any reason if you can't change the original class (to a singleton), you can consider the below approach which calls the createEntity(entityManager) inside #PostConstruct method:
public class MyRepository {
private EntityManager entityManager;
private static Client client;
#Autowired
public MyRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
#PostConstruct
public void init() {
//Now call your createEntity(entityManager) method
client = EntityUtils.createEntity(entityManager);
}
}

Related

Spring Boot: Why does #Autowired not work for this case?

I have a Spring Boot Java application and am trying to inject a #Service into a class. I'm using #Autowired but it's not doing it. I successfully do so in other classes, but not this one.
The service class:
#Service
#Transactional
public class TaskService {
...
}
The class where it works is a Vaadin "view" annotated with a Vaadin #Route annotation. I'm assuming there is something going on behind the scenes with the #Route annotation that allows this to work.
#Route("main")
public class TaskListView extends HorizontalLayout {
private final TaskService taskService;
public TaskListView(#Autowired TaskService taskService) {
this.taskService = taskService;
}
...
}
The class where it does not work is also a Vaadin "view", but does not have a #Route annotation, because it is not intended to be navigable to, but rather used as a sub-component of a view (i.e. would be directly instantiated inside a parent view).
public class EditNotesForm extends VerticalLayout {
#Autowired
private TaskService taskService;
...
}
The first class uses constructor injection, while the second uses property injection. I can't see why this should make a difference, as I have used both techniques successfully in other applications.
From the Vaadin website:
The only difference between using the router in a standard application and a Spring application is that, in Spring, you can use dependency injection in components annotated with #Route. These components are instantiated by Spring and become Spring-initialized beans. In particular, this means you can autowire other Spring-managed beans.
One way to access Spring components from your regular Vaadin components is by creating static get methods to retrieve your Spring components. Here is one way that can be done... but not the only.
#Component
public class StaticHelper {
private static StaticHelper instance;
#Autowired
private ApplicationContext applicationContext;
#PostConstruct
public void registerInstance() {
instance = this;
}
public static <T> T getBean(Class<T> class) {
return instance.applicationContext.getBean(class);
}
}
So in your example...
private TaskService taskService = StaticHelper.getBean(TaskService.class);
Since EditNotesFormdoesn't have the Route annotation, spring can't autodiscover it and therefore it can't inject any dependency.
Since you want to instantiate it manually, you'll need to provide yourself all dependencies.
But if you still want to benefit from automatic dependency injection, take a look at https://www.baeldung.com/spring-beanfactory

Declare DAO classes as class members or method arguments for Spring autowire?

I am a beginner to Spring autowire and has seen different type of autowire implementation.
There are 2 common methods as shown below to autowire persistence layer to the service layer.
Which is a better way of autowiring the persistence layer to the service layer?
#Service
public class SomeServiceImpl {
#Autowired
private CustomerDAO customerDAO;
public List<Customer> getAllCustomer() {
return customerDAO.getAllCustomer();
}
}
vs
#Service
public class SomeServiceImpl {
#Autowired
public List<Customer> getAllCustomer(CustomerDAO customerDAO) {
return customerDAO.getAllCustomer();
}
}
None of the above. Although opinionated you shouldn't use field injection (see this and this).
The second one wouldn't even work unless you would be passing the CustomerDAO around yourself.
Instead make the field final and use constructor based injection.
#Service
public class SomeServiceImpl {
private final CustomerDAO customerDAO;
#Autowired
public SomeServiceImpl(CustomerDAO customerDAO) {
this.customerDAO= customerDAO;
}
}
Still easy to test, pass the dao to the constructor and no need to pass it around. Nothing is hidden anymore (less magic) and you still honor OO rules (that an object should be in a valid state after construction).
You could even put a validation inside the constructor to check if the passed in argument isn't null.
In general, The good practice would be to put the #Autowired on a constructor instead of a method. If you put it on a constructor, you can validate that the injected beans are not null and fail fast when you try to start the application and avoid a NullPointerException when you need to actually use the bean.
There are no of advantage with
#Autowired
private CustomerDAO customerDAO;
1) You can use it into whole service class.
2) As explained above if it fail then you will notify on start the application

spring #Autowire property vs setter

What is the difference between anotate #Autowired to a property or do it in the setter?
As far as I know they both have the same result, but is there any reason to use one over the other?
UPDATE (to be more concise)
Is there a difference between this
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
private SpellChecker spellChecker;
#Autowired
public void setSpellChecker( SpellChecker spellChecker ){
this.spellChecker = spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
and this
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
#Autowired
private SpellChecker spellChecker;
public TextEditor() {
System.out.println("Inside TextEditor constructor." );
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
Sometimes you need an instance of class A, but you do not store A in the fields of the class.
You just need A instance to perform a one-shot operation. Or, you use A instance to obtain an instance of B, and you are storing B in the field.
In those cases, a setter (or constructor) autowire will suit you better.
You will not have unused class-level fields.
Concrete example:
You need to construct RabbitTemplate (an object that sends messages to RabbitMQ)
To construct it, you need ConnectionFactory
http://docs.spring.io/spring-amqp/docs/latest_ga/api/org/springframework/amqp/rabbit/core/RabbitTemplate.html#RabbitTemplate-org.springframework.amqp.rabbit.connection.ConnectionFactory-
You do not need to store that ConnectionFactory. In that case, code that looks like this:
Class MyClass {
private RabbitTemplate template;
#Autowired
void setConnectionFactory(ConnectionFactory c) {
template=new RabbitTemplate(c);
}
}
...will serve you better than directly autowiring the ConnectionFactory field.
In this example, autowiring at the constructor level would be even better, because your object will always be completely constructed. It will be clear that ConnectionFactory is a mandatory dependency, not an optional one.
With #Autowired annotation, you don't need a setter method. Once your bean's constructor is done with allocating/creating the object, Spring will scan for this annotation and would inject the object instances that you annotated.
While if you have setter and if you are still using xml config, you would explicitly set properties.
Having said that, You could annotate your constructor and setter method with autowired annotation which i would prefer as this would give me flexibility later on to move away from Spring (although i wont do it).
If you use #Autowired annotation on a property, spring will initiate the property using spring.xml. You don't need setter in this case.
If you use #Autowired annotation on a setter, you are specifying to spring that it should initiate this property using this setter method where you can add your custom code, like initializing some other property with this property.
Usage with Example:
In the case of using DAO operations using JdbcTemplate, you need DataSource as an input to JdbcTemplate, but DataSource is not required as a property in itself. So you can use DataSource Setter to initialize JdbcTempate by auto-wiring DataSource Setter. Please see the below code:
class DaoDemo{
//#Autowired
//private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
#Autowired
public void setDataSource(DataSource dataSource){
//this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int getTableRowCount(){
String sql = "SELECT COUNT(*) FROM DEMOTABLE";
//jdbcTemplate.setDataSource(dataSource); //No need to do this as its done in DataSource Setter now.
return jdbcTemplate.queryForObject(sql,Integer.class);
}
In the above code, the only use of dataSource was to get passed in JdbcTemplate. So, creating a property of dataSource doesn't make sense here. So, just use the #Autowired on setter method of DataSource bean to get its entry from spring.xml and make use of it at that particular time itself.
There are 3 types of autowiring:
Property based
#Autowired
private MyService service;
Constructor based. Note in Spring Boot you don't even need #Autowired annotation in this case:
class MyController {
private final MyService service;
public MyController(MyService service) {
this.service = service;
}
}
Setter based:
private MyService service;
#Autowired
public void setService(MyService service) {
this.service = service;
}
It is recommended to use Constructor based, then if not possible, Setter based and lastly Property based.
Why?
First, because in Constructor based you don't even use any Spring annotations. This helps you transition to different frameworks.
Second, Constructor or Setter based, make unit testing much easier. You don't need to use any Spring specific testing tools and you can only use Junit and Mockito.
Third, Constructor based is good because you can declare the property as final and not expose setters which helps with immutability and thread safety of the class.
Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing to developers to use it to wire only one or two bean definitions. With #Autowired on a field you don't need a setter method, which, on one hand makes the class smaller and easier to read, but on the other hand makes mocking the class a bit uglier.
Explicit dependencies in property and constructor-arg settings always override autowiring. You cannot autowire so-called simple properties such as primitives, Strings, and Classes (and arrays of such simple properties). This limitation is by-design.
Autowiring is less exact than explicit wiring. Spring is careful to avoid guessing in case of ambiguity that might have unexpected results, the relationships between your Spring-managed objects are no longer documented explicitly.
Wiring information may not be available to tools that may generate documentation from a Spring container.
Multiple bean definitions within the container may match the type specified by the setter method or constructor argument to be autowired. For arrays, collections, or Maps, this is not necessarily a problem. However for dependencies that expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean definition is available, an exception is thrown.
If you can, you should avoid the setter. If you don't need it, it's better when it doesn't exists, right?
I personally prefer Guice allowing me to write
public class TextEditor {
private final SpellChecker spellChecker;
#Inject public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
This goes a step further: With a final field, I know it won't ever change and I get the multithreading visibility guarantee.
There is one case where using #Autowired on an OPTIONAL property would not work.
If you want to do some initialization using that property, it might not be set before the constructor is called, and since it is optional, you cannot put it as an argument in the constructor.
In that case it is better to use an #Autowired setter method, so you can perform the initialization once the property is autowired.

Proper way of injecting dependencies?

Which one is the best way of injecting my dependencies? Why?
What is the difference between the two?
public abstract class Service {
private IConfig config;
#Inject
public Service(IConfog config) {
this.config = config
}
}
Or
public abstract class Service {
#Inject private IConfig config;
#Inject
public Service() {
}
}
Constructor injection (1st) is preferred over setter injection given that it makes it easier to support "immutable" entities or entities whose behaviour is well defined and non-modifiable after construction. Constructor vs Setter inject
For me the rule of thumb is to first prefer constructor injection and jump off to setter injection if constructor inject requires me to bend my back i.e. when working with legacy code with "OOP getter and setter" methods.
EDIT: I'm assuming you are trying to decide between "constructor" and "setter" constructor. But it also seems that you are using abstract classes which can't be instantiated. Maybe you have something else in mind?
First of all, I do not put injection-related annotations in abstract classes - in my opinion there is no sense in deciding how something should be instantiated if it actually cannot be instantiated (of course that's only my opinion with which others may agree or not).
Usually I do it in the following way:
public abstract class AbstractService {
private IConfig config;
public AbstractService(IConfog config) {
this.config = config
}
}
public class Service extends AbstractService {
#Inject
public Service(IConfig config) {
super(config);
}
}
Now, you can use both classes with and without dependency injection (construct it by hand, passing all required references). Also you can be sure that Service is instantiated in the appropriate state every time.
The main goal of dependency injection is to make unit testing easy by allowing to do
Service serviceToTest = new Service(mockConfig);
or
Service serviceToTest = new Service();
serviceToTest.setConfig(mockConfig);
The second way of injecting dependencies makes it impossible to do the abover. You can only test it by letting Guice create the service and inject a mock dependency, or by using reflection to set the mock dependency.

Injecting dependencies using #Autowired into objects created with "new ..."

I have a problem with injecting a bean into a helper class. It works basically like this: I create an object in the page constructor that does some work, returns some data and I show these on the page. In this helper object, a service should be injected via #Autowired annotation. However, I always get a null pointer exception when I use it. I also tried #SpringBean but it didn't help. On the other hand, when I inject this service directly into the page with #SpringBean, it's accessible and works fine. Do you know where the problem is?
This is the page:
public class Page extends BasePage {
public Page() {
HelperObject object = new HelperObject(new Application("APP_NAME"));
String result = object.getData();
add(new Label("label", result));
}
}
Helper object:
public class HelperObject {
private Application app;
#Autowired
private Service service;
public HelperObject(Application app) {
this.app = app;
}
public String getData() {
// use service, manipulate data, return a string
}
}
You can inject dependencies into non-Spring-non-Wicket-new-created objects using #SpringBean by calling InjectorHolder.getInjector().inject(this); in its constructor.
For example:
class MyPojo {
#SpringBean
MyDumbDAO dao;
MyPojo() {
InjectorHolder.getInjector().inject(this);
}
void justDoIt() {
dao.duh(); // dao is there!
}
}
Note that it will only work if called within a Wicket-managed request. If not (ie, if it's a Quartz job, or a Filter executed before Wicket's), the Application instance will not be available, and the injector won't know how to get the dependencies.
Another solution is to use Spring's #Configurable. It uses AspectJ to intercept creation of annotated objects, and inject its dependencies, even if you instantiate them directly with new (or some other framework, like Hibernate, creates them internally). But this requires runtime or build-time (works better for me) bytecode manipulation, which may be too much magic for some people.
#SpringBean only injects dependencies into classes that inherit from Wicket's Component. #Autowired only injects dependencies into classes created by Spring itself. That means you can't automatically inject a dependency into an object you create with new.
(Edit: you can also add a #SpringBean injection to your class by injecting in the constructor:
InjectorHolder.getInjector().inject(this);)
My normal workaround for this is to use my application class to help. (I'm a little puzzled by your use of new Application(...). I assume this isn't actually org.apache.wicket.Application.) For example:
public class MyApplication extends AuthenticatedWebApplication implements
ApplicationContextAware {
private ApplicationContext ctx;
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.ctx = applicationContext;
}
public static MyApplication get() {
return (MyApplication) WebApplication.get();
}
public static Object getSpringBean(String bean) {
return get().ctx.getBean(bean);
}
public static <T> T getSpringBean(Class<T> bean) {
return get().ctx.getBean(bean);
}
....
}
In my Spring application context:
<!-- Set up wicket application -->
<bean id="wicketApplication" class="uk.co.humboldt.Project.MyApplication"/>
My helper object then looks up the service on demand:
public class HelperObject {
private Service getService() {
return MyApplication.getSpringBean(Service.class);
}
The best practice would be to create your objects via a factory bean (that has those properties injected by Spring, and have that factory inject those properties to objects it spawns - pure IoC).
You should really avoid using SpringContext all over the place (or any other similar solution for that matter).
Here is a partial list of reasons:
Your code gets coupled with Spring way too much (low-cohesion).
You mix plumbing code with the business-logic.
Your code is less readable.
It's less maintainable (e.g., changing the name of the service bean would lead to code modification - this violates SRP & OCP).
It's less testable (e.g., you need the Spring framework to test it).

Categories

Resources