Will invoking two methods on #Stateless use the same instance? - ejb-3.0

If I have something like this-
#Stateless
public class EJBServcie{
public void method1(){
// some code goes here
}
public void method2(){
// some code goes here
}
}
with the bean using it as-
public class Bean{
#EJB
EJBService ejbService;
punlic void action(){
ejbService.method1();
ejbService.method2();
}
}
In this example, method1 is invoked on an instance of EJBService. Will method2 be invoked on the same instance?

The EJB container might choose to use the same instance depending on pooling configuration or concurrent calls, but there is no guarantee: it could choose to use a different instance for each call.

Related

Run part of a method under spring transaction

I have a method that does something like this
class EmployeeService {
#Transactional
public void perform() {
// perform DB operations()
createEmployee()
// call some async service that relies on the persisted data
runEmployeeBGV();
}
}
runEmployeeBGV() crates a separate thread which does bgv operations.
I want data to be persisted as soon as the createEmployee() method ends. But due to limitations on #Transactional(and my knowldge), I am not sure on how to exclude runEmployeeBGV() out of the scope of transaction.
Please note that these two operations need to reside within perform() method which is being called by another service class where EmployeeService is injected.
Is there any way we can achieve this without calling these methods separately from the client code?
You can move those methods to another service and move #Transaction to createEmployee()
something like that
class EmployeeService {
private EmployeeRepo repo;
private EmployeeBGV bgv;
public void perform() {
repo.createEmployee()
bgv.runEmployeeBGV();
}
}
class EmployeeRepo {
#Transactional
public void perform() {
//code
}
}

Is there a way for #SpyBean to create spies for all types based on the interface type in a Spring Boot test?

I have a Spring Boot application where I would like to ensure that a list of decorators are verified to be executed. These decorators all extend from the same Abstract class, which in turn extend from the same interface, and they are autowired into a service class as a list of decorators. I would have thought that providing the #SpyBean(MyDecorator.class) at the class level of the test would have done the trick, but I got the error specifying that the decorator is not a spy. It looks like the MockitoPostProcessor class expects that we provide the individual concrete classes in the annotation as so #SpyBean(classes = {decorator1.class,decorator2.class}). I tried the latter, and it worked.
However, the issue that I have with this is that we have to add to this list every time we create a new decorator, which is not ideal. This is why I thought it makes sense to have the interface type be checked as well. Please let me know if there is a better way of doing this, or if I missed something. A thought that crossed my mind was to define my own post processor to wrap any bean from a defined type in a mockito spy, but I would like to check here first. Here is a skeleton definition of the classes to help you understand my dilemma.
MyDecorator.java
public interface MyDecorator{
public void decorate(SomeObject obj);
}
AbstractDecorator.java
public class AbstractDecorator implements MyDecorator{
//common decorator logic
}
Decorator1.java
#Component
public class Decorator1 extends AbstractDecorator{
public void decorate(SomeObject obj){
//decoration logic
}
}
Decorator2.java
#Component
public class Decorator2 extends AbstractDecorator{
public void decorate(SomeObject obj){
//decoration logic
}
}
DecorationService.java
#Service
public class DecorationService implements Service{
#Autowired
private List<MyDecorator> decoratorList;
public void processDecorators(){
//go through list of decorators and process some object
}
}
DecoratorServiceTest.java
#Runwith(SpringRunner.class)
#SpringBootTest
#ActiveProfiles("test")
//#SpyBean(MyDecorator.class) //<-- This doesn't wrap the classes in a spy and errors out
#SpyBean(classes = {Decorator1.class, Decorator2.class}) //<-- This works
public class DecoratorServiceTest{
#Autowired
private List<MyDecorator> decoratorList;
#Test
public void testProcessDecorator(){
//verify that each decorator was processed
}
}
I posted a spring boot github issue here. Hopefully we would either see an improvement on it or we get an explanation as to why it is designed in this way.
I have a workaround in place that I'm using which is I've created a class that implements Spring's BeanPostProcessor interface, and I override the postProcessAfterInitialization method, and I check if the class is what I'm expecting, then I would wrap it in a mockito spy. Also, you would need to define the spring bean.
Here is a snippet of the class that I created.
public class SpyBeanPostProcessor<T> implements BeanPostProcessor{
/**
* The class type to spy on.
*/
private Class<T> typeToSpy;
/**
* Construct a SpyBeanPostProcessor with a class type to wrap
* as a {#link org.mockito.Spy}
* #param typeToSpy The class type to spy on.
*/
public SpyBeanPostProcessor(Class<T> typeToSpy) {
this.typeToSpy = typeToSpy;
}
#Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (typeToSpy.isAssignableFrom(bean.getClass())){
return Mockito.spy(bean);
}else{
return bean;
}
}
}
I also needed to create a new spring bean that loads the BeanPostProcessor as shown below.
#Bean
public static SpyBeanPostProcessor decoratorSpyBeanPostProcessor(){
return new SpyBeanPostProcessor(MyDecorator.class);
}

Quarkus encapsulation behavior

I have this class:
#ApplicationScoped
public class BookService {
public boolean doorClosed;
public boolean isDoorClosed() {
return doorClosed;
}
}
And I have this test class:
#QuarkusTest
public class BookServiceTest {
#Inject BookService bookService;
#Test
public void testBookServiceDoor() throws InterruptedException {
bookService.doorClosed=true;
assertTrue(bookService.doorClosed);
assertTrue(bookService.isDoorClosed());
}
}
I am surprised that the last test assertion fails. The first passes but the last fails. It almost seems like that the getter/setters are using different variables than the one I am accessing directly.
I did the same test with Spring Boot and got the two assertions passing:
#Service
public class BookService {
public boolean doorClosed;
public boolean isDoorClosed() {
return doorClosed;
}
}
And the test:
#SpringBootTest
public class BookServiceTest {
#Autowired BookService bookService;
#Test
public void testBookServiceDoor() throws InterruptedException {
bookService.doorClosed=true;
assertTrue(bookService.doorClosed);
assertTrue(bookService.isDoorClosed());
}
}
Using the #ApplicationScoped annotation makes the class a normal scoped bean. This means that the container never injects an actual instance of the class; instead, you get a proxy that will lookup the correct instance on each method invocation.
This is most commonly useful for example with #RequestScoped beans, where you get a single proxy, which will dispatch method invocations to instances that belong to the "current request" (typically an HTTP request). However, there are good reasons why you might want this for application scoped beans as well (e.g. when you want lazy initialization).
The rule is: never access fields directly on normal scoped beans, only call methods.
If you want, you can make the class #Singleton. That is a pseudo scope, and you get no proxy, you get the actual instance that you can work with directly.

How to publish a bean via static method in Spring

I'm working on a legacy Spring-Boot application where I would like to use dependency injection with some code that exists outside the application context. One a part of the application comes as a separate JAR-file and cannot be modified. But I am able to modify some classes that are instantiated in that part. Here how I'm planning to do this:
class ServiceHolder {
private static FooService fooService;
public static FooService getFooService() { return fooService; }
public static void setFooService(FooService service) { fooService = service; }
}
#Bean
#Profile("production")
FooService fooService() {
var service = new ProductionFooService();
ServiceHolder.setFooService(service);
return service;
}
public class LegacyPojo {
private final FooService fooService;
public LegacyPojo() {
fooService = ServiceHolder.getFooService();
}
//.. some business logic
}
I'm worried about possible visibility problems when different requests in separate threads will call new LegacyPojo() and reach for FooService instance.
So my question is: should I declare ServiceHolder#getFooService and ServiceHolder#setFooService synchronized or not?
There is a lot of others things you can do that with security, dont you think that you could have the instance of FooService into LegacyPojo passing it by constructor, it will be less coupled.
Other thing that you can do is to control the instances of FooService, you may do it as a singleton, declaring it as a static property on ServiceHolder and not to have a setMethod. I think, the way you told, you want a single instance of FooService.
Even LegacyPojo being a Pojo, you dont need to create a getter for FooService.
Once you use ServiceHolder.setFooService(service); you may do a implementation like this:
class ServiceHolder{
private static FooService fooService;
public static void setFooService(FooService newFooService){
if(fooService== null){
fooService = newFooService;
}
}
}
So that way, you will set only the first instance of FOoService and it will not be changed, of course you can do any condition to setFooService in ServiceHolder
It would work without any synchronization because singleton bean will be instantiated in a critical section inside synchronized block. In DefaultSingletonBeanRegistry class there is a method getSingleton which, according to the doc:
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* ...
*/
And at the very beginning of this method, the critical section starts synchronized (this.singletonObjects). So the effect of ServiceHolder.setFooService(service) call will be visible to all threads after leaving the critical section.

Trigger a second advised method from a method already being advised in Spring

I have a Class, call it X, in this class I have successfully advised a method call it method(){} from an Annotated Spring.
So, here it is:
public class X {
public void method(){...}
public void method2(){...}
}
Here is my aspect, shortened of course:
#Aspect
public class MyAspect{
#Pointcut("execution(* X.method(..))")
public void methodJP(){}
#Pointcut("execution(* X.method2(..))")
public void method2JP(){}
#Around("methodJP()")
public void doMethodJP(ProceedingJoinPoint pjp) throws Exception {
pjp.proceed(); //Amongst other things!!!
}
#After("method2JP()")
public void doMethod2JP(JoinPoint jp) throws Exception {
//Do some stuff here
}
}
Now... both join points work well, however, I within my X.method, I also call the method that is advised by method2JP()... and of course, my method2JP does not get triggered.
Is there any way I can get this to work?
Thanks.
Since Spring AOP works by proxying classes, for the advice to be invoked, you must call the method through the proxy or wrapper supplied by the bean factory.
If you don't want to break out into multiple classes, you can have the method retrieve a the proxied version of "itself" from the beanfactory. Something like this
#Service
public class MyService {
#Autowired
ApplicationContext context;
public void method1() {
context.getBean(MyService.class).method2();
}
public void method2() {
}
}
This will guarantee that the invocation of method2 from method1 will apply any aspects on the method2 pointcut.
methodJP() should be declared in another class. In the regular scenario the aspects are not triggered when you invoke a method from within the same object.

Resources