Java Spring design: all in one component? - java

Sometimes Spring components may look like this:
#Service
public final class SomeService {
#Autowired
private SomeService2 someService2;
#Autowired
private SomeService3 someService3;
#Autowired
private SomeService4 someService4;
// … and many other services
#Autowired
private SomeDao someDao;
#Autowired
private SomeDao2 someDao2;
#Autowired
private SomeDao3 someDao3;
// … and many other DAOs
}
In other words Spring components have plenty services and DAOs that are mostly repeated in other Spring components. IMHO it has the following drawbacks:
Unnecessary (boilerplate) code for autowiring most of the same components
Sometimes Spring context loading error may occur due to circular references between components
What about to use all-in-one component that combine, say, all services or all DAOs. It will contain only links to Spring components with no any business logic inside:
#Service
public final class AllServices {
#Autowired
private SomeService2 someService2;
#Autowired
private SomeService3 someService3;
#Autowired
private SomeService4 someService4;
// … and many other services
// get methods to get some service
public someService getSomeService(){};
and inject it into other components:
#Service
public final class SomeService {
#Autowired
private AllServices serv;
#Autowired
private AllDaos daos;
#Autowired
private Environment env;
// inside some code
…
serv.getSomeService().processData();
IMHO it will look more succinct without circular references issues…
What pros and cons of this approach?

The second approach might look appealing, a well-known facade pattern comes to mind at first, so I can totally understand this.
However, I think the first pattern will work better in fact and here is why:
You say that the "all-mighty" service can solve circular dependencies
Well, circular dependencies usually point on a wrong / bad design and are code smell by there own, so hiding it behind a facade won't improve the system, resolving the circular dependencies will. In addition if from the actual services, called by "AllServices" you'll want to invoke additional service (again, bad design is preserved) then the code will probably pass through AllServices again, and hence the circular dependency is still there.
Using the second design assumes that this "AllServices" class will be used by all the components of the system, but in this case it becomes a "one-central-point" and refactoring in this class can turn to a madness - all the components / their tests might be affected
Initialization of this service can become a mess by itself, since you probably won't want to maintain a constructor that has 20-30 input parameters you'll resort to field injection (like in the example) which is bad by its own because if you want to initialize it somehow, probably from test, or something you want know what should be mocked and what not, in which order, and so forth.

Second approach may look cleaner, but it will be difficult to know which service is connected to service/DAO and therefore it will be hard to refactor or do/decide on which regression any change will cause. Meaning it effect software flexibility
This is the important difference which make the difference to choose first option IMHO

Related

Mock a New Object instance in a Abstract Class

I have a AbstractDao class, where I am instantiating Rest Fore API. I am not able to mock the new forceAPI(config) in Power Mock. Please suggest.
public abstract class AbstractDao {
#Inject
private Configuration configuration;
public ForceApi getForceAPI() {
ApiConfig config = new ApiConfig();
config.setClientId("test");
config.setClientSecret("test");
config.setUsername("test");
config.setPassword("test");
config.setLoginEndpoint("test");
return new ForceApi(config);
}
}
I am trying to do in this way but it's not working.
My DAO class is extending Abstract DAO class
#RunWith(BlockJUnit4ClassRunner.class)
public class SalesForceDaoImplTest {
#InjectMocks
private SalesForceDaoImpl salesForceDao;
#Mock
private ForceApi forceApiMock;
#Mock
private ApiConfig apiConfigMock;
#Mock
private Configuration configMock;
#Mock
JsonObject jsonobject;
#Before
public void setup() {
initMocks(this);
when(configMock.getAppConfiguration()).thenReturn(jsonobject);
when(jsonobject.getString(anyString())).thenReturn("test");
when(salesForceDao.getForceAPI()).thenReturn(forceApiMock);
when(new ApiConfig()).thenReturn(apiConfigMock);
when(new ForceApi(apiConfigMock)).thenReturn(forceApiMock);
}
Probably this is a late reply, but I believe it still can be useful to some of us, programmers.
Disclaimer: I've never worked with PowerMockito but I've used PowerMock quite a lot
As for troig's suggestion:
PowerMock driven unit test assumes that you'll run with a dedicated runner:
#RunWith(PowerMockRunner.class)
In this case this clashes with #RunWith(BlockJUnit4ClassRunner.class) stated in the question, so the "slot" for RunWith is already occupied.
This particular one can still be resolved by running recent versions of power mock as a JUnit's rule (I assume you run JUnit) You can find an example of doing this here
But bottom line this is one of known issues with power mock.
There are other issues as well which basically made me to come to conclusion that the power mock should be avoided and should not be used in new project (and Power Mockito as well):
The unit test with power mock is slow (much slower than, say with EasyMock if it could be rewritten for using that)
The Power Mock sometimes instruments the byte code incompatible with tools like jacoco code coverage and as a consequence sonar doesn't cover classes unit tested with power mock or at least does it wrong
Surefire plugin responsible for running tests in maven has a feature of running multiple unit tests in parallel. Sometimes with power mock its not possible.
Even IntelliJ sometimes fails to run suits that contain power mock tests.
But the most important thing is that when you have to use tools like power mock, probably the code can (and should) be refactored to be more clean and easy-to-understand. Regarding your particular question:
Your class violates the coding principle that says that the class should not take care of dependencies of itself. Here DAO actually "constructs" and configures another (external) service for a later use.
I suggest you to watch an excellent lecture of Misko Hevery about clean code to better understand what I mean
So again, in your example. Its much better to maintain the ForceApi as a dependency constructed by Dependency Injection framework (I see that you already use #Inject so you're on the right track)
Take a look at this implementation:
public abstract class AbstractDao {
#Inject // this one is constructed and injected by your favorite DI framework in real use cases
private ForceApi forceApi;
public void doSomething() {
// do your dao stuff here
forceApi.callSomeAPIMethod();
// do your dao stuff here
}
}
Now for unit tests you don't really need power mock anymore. Its enough to use a simple Mock or even Stub depending on situation. All you need is to provide a constructor that will take a parameter of type ForceApi or maybe a setter (you can consider make it package private so that noone would be able to call it outside the test).
I don't have enough information out of your question, but the design I've offered probably can eliminate the need to have an Abstract class for the DAO, which is also can be helpful in some cases because inheritance sometimes can be a pretty heavy 'obligation' to maintain (at least think about this). And maybe in this case the inheritance is done only to support this getForceAPI behavior. In this case as the project grows, probably some methods will be added into this AbstractDAO just because its convenient to do so, but these methods will 'transparently' be added at this point to the whole hierarchy to all DAOs. This construction becomes fragile, because if at least one method changes its implementation the whole hierarchy of DAOs can potentially fail.
Hope this helps

Spring #Autowired fields - which access modifier, private or package-private?

Let's say that we use the #Autowired annotation over various fields in a class, and that we didn't write setters or constructors that can also set the fields.
Question - what should the access modifier be, private or package-private (i.e. none) ?
For example:
public class MyClass {
#Autowired
private MyService myService;
}
vs
public class MyClass {
#Autowired
MyService myService;
}
In the first case (private fields) Spring uses reflection to wire up the field, even if it doesn't have a setter.
The second case (package-private fields) allows us to be able to access those fields (for example, to set up mocks) if we need to extend the class for testing purposes.
So both cases work fine, but which is more recommended, particularly with regards to testing?
So both cases work fine, but which is more recommended, particularly with regards to testing?
I think the properties should be private:
#Autowired
private MyService myService;
As it is always good to have getter methods to provide access to the properties instead of allowing other classes to have direct access to them.
And for testing purposes, injection of mocks of private properties will work the same way as that of package-private properties.
For example, with Mockito, you can inject a mock of private MyService into MyClass as this:
public class MyClassTest {
#Mock
MyService service;
#InjectMocks
MyClass serv = new MyClass();
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
}
I generally prefer having the field private and using setter injection:
public class MyClass {
private MyService myService;
#Autowired
public void setMyService(MyService myService) {
this.myService = myService;
}
}
allowing the service to be #Autowired, but set with a mocked instance for unit testing.
The first case also allows you to inject mocks depending on the framework. For example using the #InjectMocks annotation of Mockito. You also have ReflectionTestUtils.setField in Spring test, ...
I'm personally not too fond of modifying classes too much for testing purposes, so I would go for the first case. But at the end of the day this mostly depends on your preferred test framework.
I would generally NOT use #Autowired for private fields or methods. #Autowired means, somebody from outside will set this field. "Private" on the other hand means nobody except this class is allowed to use it.
Mixing #Autowired and private can theoretically cause problems, if the JIT compiler somehow optimizes this code. It can be a Java Memory Model concurrency related problem, which will be production-only and impossible-to-reproduce.
I would make the Autowired fields at least package visible. As free bonus it will allow to write unit tests without tricks and workarounds.
UPDATE: Additionally I would declare such fields as volatile to avoid Java Memory Model related visibility conflicts. Spring developers do some tricks to make autowired fields work without explicitly synchronizing the access, but I am not sure these tricks are working smoothly in any JVM on any hardware.
I would rather use private on #Autowired fields, for a few reasons:
I use these fields for dependency injection, generally in service classes, to use other service classes. In that case I want to keep those fields to the current class.
Also, extending this class can lead to different logic, so maybe another implementation of the #Autowired fields is needed, hence the private instead of package-private.
Furthermore, when refactoring, it helps to see when such a field is not used anymore, as package-private fields don't show a warning when unused (assuming your IDE is Eclipse - I actually don't know for other IDEs).

Avoiding tight coupling between Service classes

Say I have 2 service classes:
UserService
ProductService
Is it wrong if within my ProductService class I inject the UserService?
public class ProductserviceImpl implements ProductService {
#Autowired
UserService userService;
#Override
public void someThing() {
..
userService.otherThing(..);
..
}
}
I know as an alternative I could create yet another class that injects both UserService and ProductService, but coming up with a name for this class is very tricky :) Is there a name for these types of classes in the SOA world?
1) Is it wrong if within my ProductService class I inject the UserService?
There is nothing wrong with this per se, with the following caveats:
Be aware that you could be potentially heading in the direction of one class doing too much (here, the ProductService)
Be careful that you don’t introduce cyclic dependencies (you should not have UserService also depend on ProductService)
Limit tight coupling by wiring your dependency to the interface rather than the concrete class (here you are autowiring UserService instead of UserServiceImpl, which is good)
2) Is there a name for this type of class (that injects both UserService and ProductService) ?
Yes, as was mentioned, you could call this class a Mediator since the Mediator Pattern seems to describe this.
You can have both low-level services and high-level services, with the low-level ones (ProductService, UserService) injected into the high-level ones (say, PurchaseOrderService or PurchaseOrderMediator). Alternatively, for this particular case you might think of the product service as being a single high-level service that depends on UserService. At that point it’s more about which construct is more cohesive in the context of your business logic and your application.
For me, there's no problem to inject a service into another one. That's the point with services and SOA as you said.
Services can help each others in order to give you the final result. Besides, as told JB Nizet, if there is no cyclic dependencies, no problem.
What you are describing is called Mediator Pattern.
Btw what is SOA?
Injecting one service into another using spring like you have mentioned will couple, the 2 services only to the extent of the interface used.
If you need more decoupling, think of using a message to pass between the 2 services.
Message can be strongly typed like a value object/xml with schema
or weakly typed like a HashMap
While weakly typed messages can increase the decoupling, it means you and your client will forfeit compile time checking and debugging issues will be cumbersome at runtime
What you describe is object oriented integration and most likely not a SOA one. The fact that you may get (and should avoid) cyclic dependencies demonstrate that.
If you're services know other service Java level Interfaces you are also in a big risk to introduce tight coupling.
For instance, what's the return type from the User service? is it yet another interface that belong to the User service? do you pass it around in the code of product service?

When to use autowiring in Spring

I am reading the book Pro Spring 3. It has a certain paragraph that really confused me. The paragraph is about autowiring in spring. Here is an excerpt:
In most cases, the answer to the question of whether you should use
autowiring is definitely “no!” Autowiring can save you time in small
applications, but in many cases, it leads to bad practices and is
inflexible in large applications. Using byName seems like a good
idea, but it may lead you to give your classes artificial property
names so that you can take advantage of the autowiring functionality.
The whole idea behind Spring is that you can create your classes how
you like and have Spring work for you, not the other way around ...
... For any nontrivial application, steer clear of autowiring at all
costs.
I have always been using the #Autowired tag in applications I have created. Can someone explain what is wrong with it and what I should use instead?
A mini example on how I handle most things now is:
#Service("snippetService")
public class SnippetService {
#Autowired
private TestService testService;
public Snippet getSnippet() {
return testService.getSnippet();
}
}
Is using autowiring like this "wrong" or am I missing something?
I believe there are two things confused here. What is meant by 'autowiring' in this chapter is marking bean for automated detection and injection of dependencies. This can be achieved through setting of "autowire" bean attribute.
This is in fact opposed to using #Autowired where you explicitely indicate field or setter for dependency injection.
Have a look here: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-autowire.
To explain it, assume you have
public class SnippetService {
private TestService testService;
public Snippet getSnippet() {
return testService.getSnippet();
}
public void setTestService(TestService testService) {
this.testService = testService;
}
}
If you defined a bean:
<bean class="mypackage.SnippetService" autowire="byType"/>
spring would attempt to inject bean of matching type, TestService in this case, by calling setTestService setter. Even though you did not use #Autowired. This indeed is dangerous since some setters might not be meant to be called by spring.
If you set autowire="no", nothing will be injected unless marked so with #Autowired, #Resource, #Inject.
There's nothing wrong with what you have, especially if you are starting out with one implementation of TestService anyways. As Johan mentions though, it's better to use #javax.annotation.Resource which also allows you to be more specific if you need to (for example using the name or the type attribute).
The only problem I see here is that you are loosing control a little. For example, say you have two or more instances of TestService in your app config and you want to use one of them. Having Autowire makes is trickier than using config XML to inject for you. This is what your book is trying to point i.e. it becomes difficult/trickier in big application where such needs are more frequent.
If you don't have such situations, I think its fine.
Autowire through XML is completely safe and helpful if you do constructor based autowiring particularly if you make the collaborators private final.
I'm kind shocked the author said that when I did the above on an extremely large spring 2.5 project a couple years ago. (at the time the annotation support was not working in JBoss)

Java design question

I want users to go through objectmanager for all persistence operation, instead of using UserDao directly, how can I make UserDao not visible to users. I am using spring to inject Implementation into UserDao.
public class ObjectManager {
public static UserDao USER_DAO;
#Inject
public void setUserDao(UserDao userDao) {
ObjectManager.USER_DAO = userDao;
}
}
public interface UserDao extends GenericDAO<User,Long>{
User findUserByUsername(String username);
}
what i am trying to achieve it that everyone follows one path to perform persistence operation, in my case it would be ObjectManager.USER_DAO.save(obj)..something like this instead of one developer doing userDao.save(obj)....the ObjectManger is purely for convenience. Any body can type objectManager. and the IDE will show a list of dao that are available
My advice: don't do this.
This would tightly couple your DAO classes to your central, static ObjectManager class for no obvious reason. This makes the code in your application hard to unit test, because static references like ObjectManager.USER_DAO.save(obj) can't be mocked. Also the application will be harder to maintain because any change to ObjectManager will hit nearly all your code (example future scenario: you want to move some DAO accessors out of the ObjectManager).
If you value testability and maintainability avoid global classes with static access.
It sounds like you want to add a layer between the persistence (DAO) layer and the service layer. I have a project where I do something similar, inserting a Repository layer.
When you have a layered application you can create a multi-module build and enforce dependencies between layers at build time. So the DAO layer is not on the compile-time classpath for the service layer.
You can make the Constructor private, Spring DI still will instantiate them using reflection.
Your users (programmers using your api/classes) can still instantiate classes if they use reflection too, however the normal use of "new MyClass()" will give you compile time errors. But the question remains, what do you want to achieve?
The normal way of achieving this is to change the UserDao scope to "package" level and let ObjectManager (assuming ObjectManager is part of the same package) act as a facade to it. Since UserDao is not accessible outside of the package no other client can instantiate it.
But since you are using Spring, I believe you can't do this. One work around I think of is to inject the UserDao with inner bean definition to ObjectManager. This way other code can't do a lookup using bean name or other cfg can't reference it.

Categories