AOP: basic ideas - keep objects simple? - java

I work with Spring Framework 3.0.5 and Id like to understand the basic principals of Spring. One of it is AOP.
One basic idea of the spring framework is to keep the objects itself simple and to have clear code.
DI follows this basic idea. It provides clear code and the objects itself can be very simple. The dont have to look up their dependencys.
Now what about AOP: I mean, code is for sure clearer with AOP, but does AOP also have the basic idea of keeping the objects as simple as possible? Im not sure of that, thats why Id like to know some other opinions :-)
Thanks in advance!

The main motivation for AOP is to use it for so called cross-cutting concerns, as in functionality you need to provide in basically all parts of your application, usually these include:
logging
authentication
auditing
transactionality.
AOP allows you to extract these functionalities into separate classes and just mark your classes which need these.
Watch this excellent video to get the main idea. To answer your question, yes, it will help a lot to keep your classes clean, because they will only take care about their own functionality and don't have to provide boilerplate code over and over again.

Take the following code snippets as an example. The easy way:
#PersistenceContext
private EntityManager em;
#Transactional
public void save(Object obj) {
em.persist(obj);
}
The traditional way (you can manage transactions using EntityManager interface, but that is not the point):
#PersistenceContext
private EntityManager em;
#Resource
private AbstractPlatformTransactionManager transactionManager;
public void save(final Object obj) {
new TransactionTemplate(transactionManager).execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status)
{
em.persist(obj);
}
});
}
What does it have to do with AOP? Transaction management is one of the most widely used examples of AOP and Spring is not an exception. The former code snippet uses #Transactional annotation to apply transaction demarcation using aspect, while the latter manages transactions manually. See the benefit?
The key thing: use aspects for cross-cutting concerns like logging, profiling, etc. Don't build your business logic in aspects. This way your beans remain clear while irrelevant code from business perspective is hidden in the aspect.
Also AOP allows you to do all sorts of sophisticated stuff with ease. Take for instance HTTP session handling - with session bean scope and AOP proxying you can access session without even realizing it.
To summarize - it is great tool when used for the right job.

Related

Reusing same #Transactional method for different DataSources (JdbcTemplate) in Spring

we have this code where the same service method will call different daos each using a different datasource (and different JdbcTemplates). We would like to use #Transactional annotation, but as far as I know, this annotation is always linked to a specific TransactionManager (and thus, to a specific DataSource).
So, my question is, is there a way to choose dynamically which DataSource (or TransactionManager) using when calling a #Transactional method so I can reuse that method to attack different databases?
The #Transactional annotation doesn't allow dynamic evaluation of the value attribute which selects the TransactionManager (possibly by design, at least it doesn't look like it's going to change any time soon). So you can't have something like #Transactional("#{#getTxManager}") which would resolve the tx manager at call time.
In simple cases you might be able to get away with the following, but it would only be worth considering when for example you have a primary DS, and a secondary DS that's used only in some cases. Otherwise you'd be peppering the code that selects between calling foo/bar all around, and that wouldn't look clean at all
// TX boundary on the "top" abstraction layer
#Transactional("foo")
public void foo() {
doWork();
}
#Transactional("bar")
public void bar() {
doWork();
}
private void doWork() {
// Work done here, no concern for tx management
}
For more complex cases like multitenancy, AbstractRoutingDataSource is an easy and robust choice if you haven't considered it yet. Although depending on how much switching you need, it may require tweaking or be even unsuitable.
Finally, you might be able to create your own annotation that does choose the DS dynamically (although I don't guarantee it), but that would be the riskiest approach for possible very little gains.
The safest way for you would be to create separate services for each dao... I wouldn't like to be debugging such code. Think about maintaining this code and possible failures that might happen.
If I were you I'd ask myself following questions:
1.) Why separate dbs?
2.) Isn't the context somehow mixed up? Maybe create some boundaries between them?
3.) Do my queries really need to be transactional?
I probably don't know the context of your problem but for me it seems that you've modeled your application in a wrong way and I'd focus on it.

How to set up the code for Spring + Hibernate dependency injection?

I've a newb to Java coming from C++ / C#.
My project is currently set up like this:
org.blah.config
HibernateConfig.java
org.blah.customer
Customer.java
CustomerController.java
CustomerService.java
HibernateConfig sets up the hibernate stuff and exposes the LocalSessionFactoryBean bean.
CustomerController is the REST entry point, it doesn't really have much logic, it sort of just wraps the CustomerService.java (or should I call it CustomerRepository?).
CustomerService.java (or CustomerRepository?) wraps the DB stuff. This is where I have:
#Autowired
private SessionFactory sessionFactory;
In my CustomerController, if I do:
private CustomerService customerService = new CustomerService();
it doesn't inject the sessionFactory.
From some samples I've found, people seem to create a CustomerService bean inside of HibernateConfig and then inject that into the constructor of the controller. Is that a good practice? Would I then rename my HibernateConfig to something more specific like CustomerHibernateConfig, etc.
Just trying to get an understanding of how/where to put the config & create the service / repo instance so it can be injected into the controller.
This is quite a hard question to answer in a few words. You are asking for a whole architecture that will depend a lot on the chosen design pattern, but considering you have controllers and services, let me put it this way. MVS is just a simplification and it's not a perfect approach. This will raise so many more questions like.
How much logic should go into a controller?
Should a model contain any logic?
Should a view contain logic?
Questions like these are very hard to answer, since these are very subjective. Still, I have been using Spring for a while and will give you my advise.
The controller's function is to validate inputs and a redirect to views when needed or to respond to clients' requests. If you got domain logic (aka business logic, business rules, and domain knowledge), the logic that makes business-critical decisions, then it shouldn't be on the controller, it should be on the services.
Now, I would say that you are missing a layer on your architecture, I would definitely add a DAO, which is a design pattern that defines a way to decouple the persistence layer of your application. Which is what you would understand as a Repository.
With that said, you only need one HibernateConfiguration and do the corresponding mappings in each model or XML file related to that model. I would advise to use annotations instead of XML files.
If you want to learn how to implement a Spring project that uses Hibernate, you can see how easy it is by following this Baeldung's tutorial. That page does have the best guides regarding the usage of Spring.

Best way to not DRY the same private method in several EJBs?

I have some stateless EJBs and all of them have an equal private method:
private User getLoggedinUser() {
String username = sessionContext.getCallerPrincipal().getName();
return entityManager.createNamedQuery(User.findByUsername, User.class)
.setParameter("username", username).getSingleResult();
}
What is the best way to avoid this code duplication? Outsource getLoggedinUser() into a further bean and inject this in my existing EJBs?
As a rule the EJBs should be highly cohesive and for SOA architectures tends to work like Facades (Service Facades). So, this depends on EJB responsibilities. If is an EJB that has lots of helper methods you could extract them to a specialized Service (remember that CDI supports inheritance model, could be useful to group some helpers). I prefer to avoid pass on the entityManager across methods, mainly, because loads your methods with parameters (to less the better), at the end the persistence context is shared across all the EJBs and Services that works in the same transaction.
Another way is use an Interceptor, the idea is based on Decorator pattern, but Interceptors implies a little of magic, so, use it only if you want to accomplish a precondition or a cross cutting concern.

Advice wanted on a complex structure in java (DAO and Service Layer linking/coupling)

Introduction
I am trying to make a rather complex structure in Java with interfaces, abstract classes and generics. Having no experience with generics and only average experience with creating good OOP designs, this is beginning to prove quite a challenge.
I have some feeling that what I'm trying to do cannot actually be done, but that I could come close enough to it. I'll try to explain it as brief as I can. I'm just going to tell straight away that this structure will represent my DAO and service layers to access the database. Making this question more abstract would only make it more difficult.
My DAO layer is completely fine as it is. There is a generic DAO interface and for each entity, there is a DAO interface that extends the generic one and fills in the generic types. Then there's an abstract class that is extended by each DAO implementation, which in turn implement the corresponding interface. Confusing read for most probably, so here's the diagram showing the DAO for Products as an example:
Now for the service classes, I had a similar construction in mind. Most of the methods in a service class map to the DAO methods anyway. If you replace every "DAO" in the diagram above with "Service", you get the basis for my service layer. But there is one thing that I want to do, based on the following idea I have:
Every service class for an entity will at least access one DAO object, namely the DAO of the entity that it is designed for.
Which is...
The question/problem
If I could make a proper OO design to make each service class have one instance variable for the DAO object of their respective entity my service layer would be perfect, in my view. Advice on this is welcome, in case my design is not so good as it seemed.
I have implemented it like this:
Class AbstractService
public abstract class AbstractService<EntityDAO> {
EntityDAO entityDAO;
public AbstractService() {
entityDAO = makeEntityDAO(); //compiler/IDE warning: overridable method call in constructor
}
abstract EntityDAO makeEntityDAO();
}
Class ProductServiceImpl
public class ProductServiceImpl extends AbstractService<ProductDAOImpl> {
public ProductServiceImpl() {
super();
}
#Override
ProductDAOImpl makeEntityDAO() {
return new ProductDAOImpl();
}
}
The problem with this design is a compiler warning I don't like: it has an overridable method call in the constructor (see the comment). Now it is designed to be overridable, in fact I enforce it to make sure that each service class has a reference to the corresponding DAO. Is this the best thing I can do?
I have done my absolute best to include everything you might need and only what you need for this question. All I have to say now is, comments are welcome and extensive answers even more, thanks for taking your time to read.
Additional resources on StackOverflow
Understanding Service and DAO layers
DAO and Service layers (JPA/Hibernate + Spring)
Just a little note first: usually in an application organized in layers like Presentation / Service / DAO for example, you have the following rules:
Each layer knows only the layer immediately below.
It knows it only by it's interfaces, and not by it's implementation class.
This will provide easier testing, a better code encapsulation, and a sharper definition of the different layers (through interfaces that are easily identified as public API)
That said, there is a very common way to handle that kind of situation in a way that allow the most flexibility: dependency injection. And Spring is the industry standard implementation of dependency injection (and of a lot of other things)
The idea (in short) is that your service will know that it needs a IEntityDAO, and that someone will inject in it and implementation of the interface before actually using the service. That someone is called an IOC container (Inversion of Control container). It can be Spring, and what it does is usually described by an application configuration file and will be done at application startup.
Important Note: The concept is brilliant and powerful but dead simple stupid. You can also use the Inversion of Control architectural pattern without a framework with a very simple implementation consisting in a large static method "assembling" your application parts. But in an industrial context it's better to have a framework which will allow to inject other things like database connection, web service stub clients, JMS queues, etc...
Benefits:
Your have an easy time mocking and testing, as the only thing a class depends on is interfaces
You have a single file of a small set of XML files that describe the whole structure of your application, which is really handy when your application grows.
It's a very widely adopted standard and well - known by many java developers.
Sample java code:
public abstract class AbstractService<IEntityDAO> {
private IEntityDAO entityDAO; // you don't know the concrete implementation, maybe it's a mock for testing purpose
public AbstractService() {
}
protected EntityDAO getEntityDAO() { // only subclasses need this method
}
public void setEntityDAO(IEntityDAO dao) { // IOC container will call this method
this.entityDAO = dao;
}
}
And in spring configuration file, you will have something like that:
<bean id="ProductDAO" class="com.company.dao.ProductDAO" />
[...]
<bean id="ProductService" class="com.company.service.ProductService">
<property name="entityDAO" ref="ProductDAO"/>
</bean>

What is the big idea behind the AOP implementation

I wanted to make it clear for me.
I read about AOP concept and I understood that it's a great way to share cross cutting services. (logging, security, transaction...)
But I would like to say/ask something about this idea and it's implementation.
I read there are some ways like AspectJ, JBOSS AOP in order to assimilation AOP to my business logic.
but wasnt it here already long time ago?
let's say for example I want to share a logging or security implementation amongs my components(Java beans, EJB'S, whatsoever.. )
Why couldn't I make a Singleton bean making sure it will has only one instance and as soon as any component will need it's logging/security service it would look-up and use it's service.
Why would I need to understand and have all those "Big" implementations such as aspectj or jboss AOP? What do I miss here?
The idea of AOP is to keep common logic in one place (which your singleton solution solves as well) and being "invisible" (transparent). With AOP your logging code isn't even part of the business logic, it is "injected" behind the scenes.
Also it is more dynamic - you don't need to call your singleton service every time you need logging. Just configure a pointcut once (like: "all setters in this package") and logging will be applied for all existing and new code.
Moreover AOP is much, much more flexible and powerful. You can ask the AOP implementation: "please start a transaction every time I call a method beginning with "save*" and taking one argument" or "if method returning Customer throws an exception subclassing from IllegalAgumentException, call that method again".
AOP is much more than just grouping common logic.
You have not understood what AOP is all about. The idea of AOP is to be able to write
public void foo() {
// some business code
}
instead of writing
public void foo() {
LogManager.getInstance().log("entering foo...");
SecurityManager.getInstance().checkUserInRole("fooer");
TransactionManager.getInstance().startTransaction();
try {
// some business code
TransactionManager.getInstance().commit();
}
catch(RuntimeException e) {
TransactionManager.getInstance().rollback();
throw e;
}
LogManager.getInstance().log("leaving foo...");
}
All the cross-cutting concerns (logging, security, transaction management) are outside of the business code, instead of being mixed with the business code, and repeated ad nauseam.

Categories

Resources