I am configuring the shiro-spring-starter.
#Configuration
public class ShiroConfig {
#Bean
public Realm realm() {
return new UserRealm();
}
}
\\Without #Component
public class UserRealm extends AuthorizingRealm {
#Autowired
private UserMapper userMapper;
}
UserRealm was create using "new UserRealm()",without #Component.
why the #Autowired work?
In your code, the #Component annotation is not required because you've created the UserRealm object as a spring bean in the ShiroConfig class. Since it's a spring bean, spring will manage the object and perform the dependency injections specified by the #Autowired annotation.
If you didn't create the UserRealm object as a spring bean in the ShiroConfig class, you would then need the #Component annotation on the UserRealm class. The #Component annotation would cause spring to automatically create an instance of the UserRealm class as a spring bean, assuming component scanning is enabled.
So you either don't use a #Component annotation and manually create spring beans in your configuration class, or use the #Component annotation and let spring automatically create the spring bean. The result is the same.
Related
I read about the component scan and as I understood that configuration classes are auto-scanned. my question if I have the following:
#Configuration
public class AppConfig {
#Bean(name="authenticationService")
public AuthenticationService getAuthenticationService(){
return new AuthenticationService();
}
}
if the #Configuration is already scanned (so the app config will be available ), wouldn't be the bean inside it created? I'm little confused as they say the #Bean is not auto scanned
No. Spring won't scan #Bean methods.
Here, you are creating the bean of AuthenticationService just like in any other java program using new keyword.
It is same as AuthenticationService authenticationService = new AuthenticationService();
If you want spring to create a bean of AuthenticationService in AppConfig class, use #Autowired annotation
#Autowired
private AuthenticationService authenticationService;
Hope this helps!
EDIT :
#M.Deinum corrected me that spring doesn't create beans based on #Autowired annotation. Beans are created automatically by spring if their classes are annotated with #Component/ #Configuration / #Service annotations.
#M.Deinum, Thank you.
I have 3 classes which are found in different packages in a spring boot application as follows:
Why does #Autowired work in certain classes only?Anything I am doing wrong?
#Configuration
public class Configurations{
#Autowired
Prop prop; //works fine
#Bean
//other bean definitions
}
#Component
public class Prop{
public void method(){};
}
public class User{
#Autowired
Prop prop; //does not work, null
public void doWork(){
prop.method();
}
}
I have also tried the #PostConstruct, but same result
public class User{
#Autowired
Prop prop; //does not work, null
#PostConstruct
public void doWork(){
prop.method();
}
}
The #Autowired annotation works only if Spring detects that the class itself should be a Spring bean.
In your first example you annotated Configurations with the #Configuration annotation. Your User class on the other hand does not have an annotation indicating that it should be a Spring bean.
There are various annotations (with different meanings) to make your class being picked up by the Spring container, some examples are #Service, #Component, #Controller, #Configuration, ... . However, this only works if your class is in a package that is being scanned by the Spring container. With Spring boot, the easiest way to guarantee that is by putting your User class in a (sub)package of your main class (the class annotated with #SpringBootApplication).
You can also manually create your bean by writing the following method in your Configurations:
#Bean
public User user() {
return new User();
}
In this case you don't have to annotate your User class, nor do you have to make sure that it is in a package that is being scanned.
Spring only autowires beans to fields/setters/constructors which are annotated with #Resource, #Autowired (not considering Java Config and XML configuration).
Is there a way to configure Spring to automatically guess where the #Resource/ #Autowired annotations could be placed and do the autowiring based on that?
Here's how it works in Grails:
class BookController {
def bookService
…
}
How can I make it working in Spring?
#Controller
public class BookController {
BookService bookService
…
}
I have this HTTP listener subclass
public class MigificSessionListener implements HttpSessionListener {
#Autowired
#Qualifier("notificationThread")
private NotificationThread notificationThread;
#Override
public void sessionDestroyed(HttpSessionEvent hse) {
// here notificationThread value is null
}
}
Value of notificationThread inside sessionDestroyed() is null.
How can i autowire sessionDestroyed inside this class ?
Your MigificSessionListener in not in your spring conext, spring even do not know it exists.
You can use WebApplicationContextUtils to get your spring context from ServletContext
WebApplicationContextUtils.getWebApplicationContext(sessionEvent.getSession().getServletContext())
You can enable Spring AOP with #EnableSpringConfigured and annotate your class with #Configurable. This let spring manage instances which are created outside the spring context with new. You will also need to enable either load-time weaving or compile-time weaving. This is documented in 9.8.1 Using AspectJ to dependency inject domain objects with Spring.
#Configuration
#EnableSpringConfigured
public class AppConfig {
}
#Configurable
public class MigificSessionListener implements HttpSessionListener {
#Autowired
#Qualifier("notificationThread")
private NotificationThread notificationThread;
//...
}
Convert your non-Spring managed class MigificSessionListener into a Spring-managed one by annotating it with #Configurable.
For this annotation to be recognised you need <context:spring-configured/> in your Spring XML config or #EnableSpringConfigured if you are using Spring Java config.
The #Autowired or injection of other dependencies will then succeed.
How do I initialize List inside Object using Spring Annotation
#Component
class Accounts{
private List<Transaction> _transaction;
//getter setter
}
How do I initialize List<Transaction> _transaction; using Spring Annotation or else i
have to define it in xml file.
But i dont want to write any xml file
You can use the Spring Java #Configuration for such a task:
#Configuration
public class SpringConfig {
#Bean
public List<Transaction> transactions() {
...... //Your logic to generate the list..
return transactions;
}
}
And in your Accounts class you have to use #Resource, not #Autowired, the semantics of injecting a list is a little different - if you use #Autowired, any bean of the same type will get injected into the list.
#Component
class Accounts{
#Resource(name="transactions")
private List<Transaction> _transaction;
//getter setter
}
This is pure java solution and there is no xml involved in creating the list..
If Transaction is a Bean with #Service, #Component or #Repository Annotation, you can just write #Autowired on top of your field.
#Component
class Accounts{
#Autowired
private List<Transaction> _transaction;
//getter setter
}