Spring: #Bean can still work without #Configuration - spring

From https://projects.spring.io/spring-framework/ I have a spring framework hellpworld program. I delete the annotation #Configuration. However the program could still run as before. Why? What is #Configuration role here?

You can still mark the class with #Component for #Bean instances to be available to program. when you do that it is called lite mode. In this mode you can not use 'inter-bean references' , means referring other instance via methods.
On the the other hand #Bean with class #Configuration is wrapped in side cglib wrapper where any calls to this bean methods can be intercepted and bean instances can be return from context. Means you can use 'inter-bean references'.
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html
#Bean Methods in #Configuration Classes
Typically, #Bean methods are declared within #Configuration classes.
In this case, bean methods may reference other #Bean methods in the
same class by calling them directly. This ensures that references
between beans are strongly typed and navigable. Such so-called
'inter-bean references' are guaranteed to respect scoping and AOP
semantics, just like getBean() lookups would. These are the semantics
known from the original 'Spring JavaConfig' project which require
CGLIB subclassing of each such configuration class at runtime. As a
consequence, #Configuration classes and their factory methods must not
be marked as final or private in this mode.
#Bean Lite Mode
#Bean methods may also be declared within classes that are not
annotated with #Configuration. For example, bean methods may be
declared in a #Component class or even in a plain old class. In such
cases, a #Bean method will get processed in a so-called 'lite' mode.
Bean methods in lite mode will be treated as plain factory methods by
the container (similar to factory-method declarations in XML), with
scoping and lifecycle callbacks properly applied. The containing class
remains unmodified in this case, and there are no unusual constraints
for the containing class or the factory methods.
In contrast to the semantics for bean methods in #Configuration
classes, 'inter-bean references' are not supported in lite mode.
Instead, when one #Bean-method invokes another #Bean-method in lite
mode, the invocation is a standard Java method invocation; Spring does
not intercept the invocation via a CGLIB proxy.
And,
#Configuration gives you the ability use many other features with conjunction of other annotations
Importing other config
#Import(DatabaseConfig.class)
resource import #PropertySource("classpath:config.properties")
enable component scan #ComponentScan(basePackages = { "com.sample.*" })
marking profile #Profile("production")
To enable features #Enablexxxx
http://docs.spring.io/spring-framework/docs/4.0.4.RELEASE/javadoc-api/org/springframework/context/annotation/Configuration.html

Related

How to make a bean discoverable by Quarkus CDI without using annotations

I have a simple Quarkus resource:
#Path("/rosters")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class RosterResource {
private final RosterService rosterService;
public RosterResource(RosterService rosterService){
this.rosterService = rosterService;
}
#GET
#Path("/{rosterId}")
public Response getRoster(#PathParam("rosterId")Long rosterId){
return Response.ok(rosterService.getRosterById(rosterId)).build();
}
}
I am trying to inject the RosterServiceinstance in my resource, but I am getting a javax.enterprise.inject.UnsatisfiedResolutionException. However, if I use the #ApplicationScoped annotation on RosterService, then everything works just fine. Is there a way of injecting the RosterService class in my resource without using annotations? In other words, is there a way of making RosterService discoverable by the Quarkus container without directly annotating the class?
Edit: looking into the CDI docs, it seems that you can manually register beans using a method with a #BuildStep annotation. However, it is not clear to me which class should contain the annotated method)
Another option would be to use a Jandex index
To the best of my knowledge, Quarkus only implements so called annotated bean discovery. That means that all CDI beans in Quarkus have to have a bean defining annotation. #ApplicationScoped is one of them.
EDIT: regarding a Jandex index, that allows you to scan for beans in additional JARs. In other words, it will only expand the set of classes that are scanned for a bean defining annotation.
When it comes to a #BuildStep method -- that is only possible in a Quarkus extension. Extensions are powerful (and indeed they can define additional beans) but also complex. You can start at https://quarkus.io/guides/building-my-first-extension, but it may feel overwhelming. It may also feel like this is not the right thing to do if you want to just make your class a bean -- and that would be true. But if your class comes from an external library that you can't change, extension makes sense.
Is there a specific reason why you don't want to annotate your service class with #ApplicationScoped (or any other of the bean discover/scope annotations)?
The only other way that I'm aware of (instead of annotations) is - as you yourself mentioned - the use of Jandex index.

Is it good to add #Component or #Bean in POJO classes in Java?

My Scope of the object is in Method level, Is it good to decorate a POJO class with
#Componet or #Bean with scope request or prototype, So that we could inject it in the required class to avoid Object Instantiation by manual.
Is it a good practice?
What to annotate?
Within the Spring Framework, only use the #Bean annotation in classes marked with #Configuration.
Although possible to use the #Bean within #Component classes, it is not recommended, since you will be creating light beans (Which is considered bad practice and can lead to unintended side effects).
When to use #Bean vs #Component?
The golden rule, use #Component (Or #Service) in your own classed, and #Configuration + #Bean for third-party code.
What not to annotate with #Component or #Bean
Do not annotate domain classes or Entities (For example your person class), only classes that are considered to be stateless. (Like your ManagerPerson / **Service class).
Do not annotate your DTOs.
If you have any of these currently annotated, I would strongly recommend first jumping back to Spring Framework tutorials.
What about scope?
Go have a look at https://www.baeldung.com/spring-bean-scopes
There are only a couple namely:
Singleton (Default scope) Single Spring Bean Instance for the application - Same Instance that is being used all over the application.)
Prototype (New bean for where ever it is used)
Request (Spring Bean per Request only for Spring MVC)
Session (Spring Bean per Session only for Spring MVC)
Custom Scope (Yes you can create your own... but don't ;) )

How SpringBoot dependency injection works with different type of annotations

I recently started exploring Spring Boot. I see that there are 2 ways to define Beans in Spring Boot.
Define #Bean in the class annotated with #SprinBootApplication
Define #Bean in a class annotated with #Configuration
I am also confused about stereo-type annotation #Repository #Service #Controller etc.
Can someone please explain how dependency-injection works with these annotations?
Yes it is possible.
Either you use #Bean in any of your #Configuration or #SpringBootApplication class or mark the bean classes explicitly with annotations like #Service, #Component #Repository etc.
#Service or #Component
When you mark a class with #Service or #Compoenent and if spring's annotation scanning scope allows it to reach to the package, spring will register the instances of those classes as spring beans.
You can provide the packages to be included/excluded during scan with #ComponentScan
#Bean
#Beans are marked on factory methods which can create an instance of a particular class.
#Bean
public Account getAccount(){
return new DailyAccount();
}
Now in you application you can simply #Autowire Account and spring will internally call its factory method getAccount, which in turn returns an instance of DailyAccount.
There is a simple difference of using #Bean vs #Service or #Compoenent.
The first one makes your beans loosely coupled to each other.
In the #Bean, you have flexibility to change the account implementation without even changing any of the account classes.
Consider if your classes instantiation is a multi-step operation like read properties values etc then you can easily do it in your #Bean method.
#Bean also helps if you don't have source code access to the class you are trying to instantiate.
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added.
You need to opt-in to auto-configuration by adding the #EnableAutoConfiguration or #SpringBootApplication annotations to one of your #Configuration classes.
You are free to use any of the standard Spring Framework techniques to define your beans and their injected dependencies. For simplicity, we often find that using #ComponentScan (to find your beans) and using #Autowired (to do constructor injection) works well.
One way is to define #Bean in the class annotated with
#SprinBootApplication
If you see #SprinBootApplication it is combination of many annotation, and one of them is #Configuration. So when you define #Bean in the Main class, it means it's inside #Configuration class.
According to Configuration docs :
Indicates that a class declares one or more #Bean methods and may be
processed by the Spring container to generate bean definitions and
service requests for those beans at runtime.
class annotated with #Configuration
When you define #Bean is a class annotated with #Configuration class, it means it is the part of spring configuration all the Beans define in it all available for Dependency-Injection.
I have also seen some code where neither of the 2 above approaches
have been used and yet dependency injection works fine. I have tried
to research a lot on this but could not find any concrete answer to
this. Is this possible?
I am assuming you are talking about Sterio-type annotation. Every sterio type annotation has #Component, according to docs :
Indicates that an annotated class is a "component". Such classes are
considered as candidates for auto-detection when using
annotation-based configuration and classpath scanning.

Spring Java config, #Autowire vs. Constructor Injection, #Transactional and CGLIB

We've been using #Autowired plus Java-based Spring configuration with some success but now, we're losing control. Everyone is starting to add autowired dependencies everywhere, creating cycles and strange bugs.
So we are considering using constructor injection and autowiring of Spring configurations.
Old:
class Bean {
#Autowired Foo foo;
}
#Configuration
#Import( FooCfg.class )
class BeanCfg {
#Bean public Bean bean() { return new Bean(); }
}
New:
class Bean {
public Bean(Foo foo) {...}
}
#Configuration
class BeanCfg {
#Autowired FooCfg fooCfg;
#Bean public Bean bean() { return new Bean(fooCfg.foo()); }
}
This works pretty well (and it drives people to split beans instead of creating monsters with 10+ constructor arguments).
But it fails when Bean has a method annotated with #Transactional since CGLIB then tries to create a proxy which fails since it can't find a no-argument constructor.
What's the solution for this?
You have a couple of possible of solutions
Introduce interfaces your classes
Upgrade the Spring Version to at least 4.0
Add protected no-arg constructor
Introduce Interfaces
When introducing interfaces for your classes you can drop the usage of CgLib. Spring will then be able to use JDK Dynamic Proxies which work around interfaces. It creates a proxy around an already existing bean instance and that proxy implements all the interfaces of the class it is wrapping. That way it doesn't matter if your class has a no-arg constructor or not.
Upgrade to Spring 4
In Spring 4.0 support was added to allow proxying of classes with a missing no-arg constructor (See SPR-10594). To enable this upgrade your Spring version and add Objenesis to your classpath, Spring 4 comes with its own repacked cglib version so that shouldn't be needed anymore.
One thing to note is that you should have a constructor with no logic if you do null checks or init logic in the constructor it might fail in the case where cglib creates an instance. I would suspect that it pass null to all the constructor arguments (or some default for primitives).
Added protected no-arg constructor
Cglib needs to be able to create an instance which is used to wrap the actual class. It should be enough to have a protected constructor in your classes so that cglib can call it.

Why proxy is not used to autowire

I can not find any reason why every autowired bean are not autowired by proxy. I know that becasue #Transactional annotations do not work and I checked autowired component during debugging in eclipse. Of course every component implements some interface and I use #Autowired annotations in relation to the interface.
I have only one configuration of aop:
<tx:annotation-driven transaction-manager="transactionManager" />
I use JPA with hibernate, spring-mvc,spring-webflow, spring-security and spring-data. Interfaces which extends org.springframework.data.repository.CrudRepository are autowired by proxy. But my components are not. For example I have class MyClass which implement MyInterface:
#Service
public class MyClass implements MyInterface {
#Autowired
MyCrudReposiotry reposiotry;
....
}
If I autowire MyInterface somewhere:
#Autowired
MyInterface mi;
then mi is just reference to MyClass object, repository is refrence to proxy org.springframework.aop.framework.JdkDynamicAopProxy. Very interesting is that in testing mi is reference to proxy. My test's context does not contain web-flow and mvc configuration.
Maybe there is some indirect aop configuration which I should check. What can switch the autowiring by proxy off?
My guess is that you are scanning for the same components twice. You probably have a in your root context (for the ContextLoaderListener) and one for the DispatcherServlet. NO if the both scan for the same classes you end up with duplicated (and one proxied and one non proxied instance).
Proxying and auto wiring are independent of each other. When you use #AutoWired it finds another bean that implements the required interface and injects it. The bean instance it finds might be a normal object or a proxy - it doesn't matter to Autowired.
Proxies are created for certain beans automatically by spring. As you have noticed one scenario in which this happens is when you use #Transactional. When the spring container instantiates a bean which has the #Transactional annotation the object gets wrapped in a proxy. The actual object is replaced by the proxy in the context. This is done so that spring can intercept calls to those methods and add the begin / commit transaction calls before and after the method call. This is implemented by the spring-aop module. Any feature that relies on AOP (#Transactional, #Secured) will result in creation of a proxy.
The other case where proxies are used is to create an implementation on the fly. In case of the CRUDRepository you are required to only implement the interface. The implementation of that is created on the fly using the same proxy infrastructure.

Resources