Autowiring working in one class but not in other - java

I have an autowired class like this
#Component
public class APIPermissionCheck {
..............
}
its injecting fine in one java file. But its always returning null in other java file. What could be the possible cause of this? How to debug/fix this issue?
working fine in this class
#Repository("MyClassRepo")
public class MyClassRepoImpl implements MyClassRepo {
.......
#Autowired
private APIPermissionCheck apiPermissionCheck;
.......
}
Not working in this class
public class ApiConnection {
.......
#Autowired
private APIPermissionCheck apiPermissionCheck;
.......
}

The class ApiConnection is not found by spring because it is neither annotated as #Component neither as #Repository.
If you annotate your class with #Component it should work.
Also ensure that the package with the class is scanned by spring.

Does your second class marked as spring bean?
Do you scan the package in which your second class by spring?
you can view configuration sample at spring site
EDIT :
Create a setter for the bean you're trying to inject
public void setApiPermissionCheck(APIPermissionCheck apiPermissionCheck){
this.apiPermissionCheck = apiPermissionCheck
}

Try to add an interface to ApiConnection to verify it's being loaded by Spring Container.
ApiConneection implements ApplicationContextAware {
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
logger.info("Initializing context is:" + applicationContext);
}
....
}
do the same for the Autowiring classes and verify they are being loaded withint the same context.
You problem is probably:
The bean is not initialized with a spring
Autowired beans belongs to another context
Context for ApiConnection is not instructed with <context:annotation-config/>

I found the solution. As ApiConnection object is being created a lot of places manually so spring framework is not autowiring it.

I met the same problem and solved it by adding a #Service to the second class public class ApiConnection. The first class already has a #Service. In this step, it still does not work (return NullPointerException). In addition, in the Class that use ApiConnection, let's say ApplicationImpl, I add #Autowired on ApiConnection apiConnection; (ApiConnection apiConnection = new XXX was used before). Then it works.

Related

Cannot Inject Service in HandlerInterceptorAdapter, Getting NullPointerException

I have a service-client project which is in normal spring application , not spring boot .its used for mainly logging related things.which contains Interceptor , loggingservice impl class and some model classes for logging. I have added this module as a dependency to main application in pom.xml.and i was able to inject and use the loggingService beans within the service layers of the main application.
Am getting NullPointerException while auto-wiring loggingService within the interceptor .The bean is not available within the interceptor.but like i said it can be injected and used within the main application.
Also am not able to read properties using #Value within the interceptor.
This is my Interceptor class .
#Component
public class LoggingInterceptor extends HandlerInterceptorAdapter {
#Autowired
LoggingService loggingService;
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
loggingService.info("Am in prehandle");
return true;
}
}
This is my configuration class where i register the interceptor with the main application
#Component
public class LoggingConfig implements WebMvcConfigurer {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getLoginInterceptor());
}
#Bean
public LoggingInterceptor getLoginInterceptor() {
return new LoggingInterceptor();
}
}
My question is almost similar to this post Cannot Autowire Service in HandlerInterceptorAdapter , but its different like am referring the interceptor from another module , and like they suggested i tried to create the bean from the application.
But the issues am facing right now is
getting NullPointerException while injecting loggingService within interceptor, but its working in main application
#Value annotation also return null, not able to read from properties
You have 2 possible solutions.
Mark your LoggingConfig as #Configuration instead of #Copmponent
Inject the LoggingInterceptor instead of referencing the #Bean method
Option 1: LoggingConfig as #Configuration
Your LoggingConfig is marked as an #Component whereas it should be marked as an #Configuration. The difference is that whilst it is allowed to have an #Bean method on an #Component it operates in a so-called lite mode. Meaning you cannot use method references to get the instance of a bean (this is due to no special proxy being created). This will lead to just a new instance of the LoggingInterceptor being created but it isn't a bean.
So in short what you are doing is equivalent to registry.addInterceptor(new LoggingInterceptor()); which just creates an instance without Spring knowing about it.
When marking the LoggingConfig as an #Configuration a special proxy will be created which will make the LoggingInterceptor a proper singleton bean, due to the method call being intercepted. This will register the bean in Spring and you will be able call the method.
NOTE: You actually endup with 2 instances of the LoggingInterceptor one due to the #Component on it the other through the #Bean. Remove the #Component.
Option 2: Inject the LoggingInterceptor.
As your LoggingInterceptor is marked as an #Component Spring will already create an instance (you actually have 2 instances of it created in your current setup). This instance you can inject into your LoggingConfig.
#Component
public class LoggingConfig implements WebMvcConfigurer {
private LoggingInterceptor loggingInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loggingInterceptor);
}
}
With this you can remove the #Bean method as you will get the proper one injected into your LoggingConfig class. The class can also remain an #Component in this case. Although I would recommend using #Configuration as to also properly stereotype it.
NOTE: If you are on a recent Spring version you can use #Configuration(proxyBeanMethods=false). This will make a lite-configuration (just like an #Component) but it is still marked properly as a configuration class.

Spring Boot: The bean 'auditLogDao' could not be injected as a 'AuditLogDao' because it is a JDK dynamic proxy

I am getting the following error in a Spring Boot project on which I work:
The bean 'auditLogDao' could not be injected as a '{redactedpathwithcorporatename}.AuditLogDao' because it is a JDK dynamic proxy that implements:
org.springframework.data.jpa.repository.JpaRepository
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on #EnableAsync and/or #EnableCaching.
I have tried a variety of solutions on StackOverflow without success, specifically:
Checking that I am indeed calling the interface, not the implementation.
Adding #Component to the top of SwitchUserFilter
Changing #Resource to #Autowired.
AuditLogDao.java
public interface AuditLogDao extends JpaRepository<AuditLog, String> {}
AuditLogService.java
public interface AuditLogService {
AuditLog save(final AuditLog auditLog);
}
AuditLogServiceImplementation.java
public class AuditLogServiceImplementation implements AuditLogService{
#Resource private AuditLogDao auditLogDao;
#Override
public AuditLog save(AuditLog auditLog) {
return auditLogDao.save(auditLog);
}
}
The file where I actually want to use the service to save information
SwitchuserFilter.java
public class SwitchUserFilter
extends org.springframework.security.web.authentication.switchuser.SwitchUserFilter {
#Resource AuditLogService logService;
'''
logService.save(auditLog);
'''
}
I am relatively new to Spring Boot, so an explanation of why it fixes the problem would be appreciated.
I believe the following code will solve your problem. Add it to the AuditLogServiceImplementation and remove the #Resource annotation from the auditLogDao.
#Autowired
private ListableBeanFactory beanFactory;
#EventListener({ContextRefreshedEvent.class})
void contextRefreshedEvent() {
auditLogDao = beanFactory.getBean(AuditLogDao.class);
}
You can do a similar trick in the filter too, whatever more comfortable for you.
I don't know what is the exact problem, but it's some kind of circular-dependency-like issue.
So by manually importing any bean which is affected in this loop, you can resolve the loop. You will set this one particular dependency AFTER Spring had created all of the other beans.

Class instantiation using the Autowired annotation

Is its advisable to instantiate the class using #Autowired annotation like below.
#Autowired
public static Car = new Car();
Case 1
If you are trying to autowire an attribute like following:
#Autowired
public Car car;
then Spring will try to search for a Bean definition in Spring context and will also instantiate it, hence no need to again invoke constructor.
Case 2
If you are getting confused with constructor autowire like following:
#Autowired
public Driver(License license){
this.license = license;
}
Here, it is trying to get the Bean of "License" class autowired, and it is not autowireing Driver.
In your case, I feel it is case 1.
If you are trying to set it manually cause you are seeing it as not initialized, then check the spring application context configuration file/class. You will need to have something like following in it:
<context:component-scan base-package="com.test.packagename" />
If using AppConfig class then:
#Configuration
#ComponentScan("com.test.packagename")
public class AppConfig {
}
Also, make sure that your spring core is deployed in lib where it is executing.
Also check that you are instantiating the class by using Spring application context as follows:
AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Car car= (Application)context.getBean("car");
Try to refer this: http://websystique.com/spring/spring-dependency-injection-annotation-beans-auto-wiring-using-autowired-qualifier-resource-annotations-configuration/
Happy coding DBZ fan :-)

Transactional annotation error

When I put "#Transactional(readOnly=false)" annotation in my Service class I get the following error
Description:
The bean 'studentService' could not be injected as a
'com.student.service.StudentServiceImpl' because it is a JDK dynamic
proxy that implements: com.student.service.StudentService
Sample code:
#Service("studentService")
#Transactional(readOnly=false)
public class StudentServiceImpl implements StudentService {
}
public interface StudentService {
}
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on #EnableAsync and/or #EnableCaching.
Process finished with exit code 1
What is causing this?
As SO already mentioned on the comment, the error occurs when you are trying to inject/autowire the implementation class instead of interface.
The bean 'studentService' could not be injected as a
'com.student.service.StudentServiceImpl' because it is a JDK dynamic
proxy that implements: com.student.service.StudentService
On the setup posted by SO,
public class StudentServiceImpl implements StudentService {
}
public interface StudentService {
}
If you autowire the interface as below you won't get an error:
#Autowired //or #Inject
StudentService studentService;
in spring boot projects, try to add :
spring.aop.proxy-target-class=true
to your application.properties
OR
#EnableAspectJAutoProxy(proxyTargetClass = true)
to your spring boot entry point.
In your application class file add this:
#SpringBootApplication
#EnableCaching(proxyTargetClass = true)
I had similar problem and resolved in this way

How to inject dependencies into a self-instantiated object in Spring?

Let's say we have a class:
public class MyClass {
#Autowired private AnotherBean anotherBean;
}
Then we created an object of this class (or some other framework have created the instance of this class).
MyClass obj = new MyClass();
Is it possible to still inject the dependencies? Something like:
applicationContext.injectDependencies(obj);
(I think Google Guice has something like this)
You can do this using the autowireBean() method of AutowireCapableBeanFactory. You pass it an arbitrary object, and Spring will treat it like something it created itself, and will apply the various autowiring bits and pieces.
To get hold of the AutowireCapableBeanFactory, just autowire that:
private #Autowired AutowireCapableBeanFactory beanFactory;
public void doStuff() {
MyBean obj = new MyBean();
beanFactory.autowireBean(obj);
// obj will now have its dependencies autowired.
}
You can also mark your MyClass with #Configurable annotation:
#Configurable
public class MyClass {
#Autowired private AnotherClass instance
}
Then at creation time it will automatically inject its dependencies. You also should have <context:spring-configured/> in your application context xml.
Just got the same need and in my case it was already the logic inside non Spring manageable java class which had access to ApplicationContext. Inspired by scaffman.
Solved by:
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
factory.autowireBean(manuallyCreatedInstance);
I used a different approach. I had spring loaded beans that I wanted to call from my extended classes of a third-party library that created its own threads.
I used approach I found here https://confluence.jaytaala.com/display/TKB/Super+simple+approach+to+accessing+Spring+beans+from+non-Spring+managed+classes+and+POJOs
In the non-managed class:
{
[...]
SomeBean bc = (SomeBean) SpringContext.getBean(SomeBean.class);
[...]
bc.someMethod(...)
}
And then as a helper class in the main application:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
#Component
public class SpringContext implements ApplicationContextAware
{
private static ApplicationContext context;
public static <T extends Object> T getBean(Class<T> beanClass)
{
return context.getBean(beanClass);
}
#Override
public void setApplicationContext(ApplicationContext context) throws BeansException
{
SpringContext.context = context;
}
}
I wanted to share my solution that follows the #Configurable approach as briefly mentioned in #glaz666 answer because
The answer by #skaffman is nearly 10 years old, and that does not mean not good enough or does not work
The answer by #glaz666 is brief and didn't really help me solve my problem but, did point me in the right direction
My setup
Spring Boot 2.0.3 with Spring Neo4j & Aop starts (which is irrelevant anyway)
Instantiate a bean when Spring Boot is ready using #Configurable approach (using ApplicationRunner)
Gradle & Eclipse
Steps
I needed to follow the steps below in order to get it working
The #Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = false) to be placed on top of your Bean that is to be manually instantiated. In my case the Bean that is to be manually instantiated have #Autowired services hence, the props to above annotation.
Annotate the Spring Boot's main XXXApplicaiton.java (or the file that is annotated with #SpringBootApplication) with the #EnableSpringConfigured and #EnableLoadTimeWeaving(aspectjWeaving=AspectJWeaving.ENABLED)
Add the dependencies in your build file (i.e. build.gradle or pom.xml depending on which one you use) compile('org.springframework.boot:spring-boot-starter-aop') and compile('org.springframework:spring-aspects:5.0.7.RELEASE')
New+up your Bean that is annotated with #Configurable anywhere and its dependencies should be autowired.
*In regards to point #3 above, I am aware that the org.springframework.boot:spring-boot-starter-aop transitively pulls the spring-aop (as shown here mavencentral) but, in my case the Eclipse failed to resolve the #EnableSpringConfigured annotations hence, why I explicitly added the spring-aop dependency in addition to the starter. Should you face the same issue, just declare the dependency or go on adventure of figuring out
Is there a version conflict
Why the org.springframework.context.annotation.aspect.* is not available
Is your IDE setup properly
Etc etc.
This worked for me:
#Configuration
public class AppConfig {
#Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
See more information: https://docs.spring.io/spring-javaconfig/docs/1.0.0.m3/reference/html/creating-bean-definitions.html
Found the following way useful for my use case. Sharing here for reference, credit goes to the blogger entirely. This creates a static field and populates that from Spring and then provides a public static method which returns the field populated above.
https://sultanov.dev/blog/access-spring-beans-from-unmanaged-objects/

Categories

Resources