Architectural Enforcement Using Spring/AspectJ - java

I have a Spring project uses annotations to apply (among other things) caching.
My understanding is that these annotations will only work when #Autowired and called through SpringAOP.
This means that if a method calls another in the same class, then any annotations on the second method are ignored e.g.
#Cacheable(...)
public Animal getAnimal(int id) {
return get(m_url, id);
}
public Cage getCagedAnimal(int id) {
Animal animal = getAnimal(id); // This call will not apply #Cacheable
Cage cagedAnimal = new Cage(animal);
return cagedAnimal;
}
What I am looking for is a way to enforce against this i.e. public methods should not be able to call other public methods of the same class.
I tried applying something similar to the approach used here http://www.jayway.com/2010/03/28/architectural-enforcement-with-aid-of-aspectj but it falls short when applying the restriction on the same class.

It's perfectly doable, AspectJ is very powerful. But you seem to be using Spring AOP instead of AspectJ, and Spring AOP is quite limited compared to AspectJ. Spring AOP works by creating proxies around your actual bean implementation to implement the AOP features it provides. When the proxy gets the call, the advices will be applied and flow control will be passed to the normal bean. Should the normal bean (the target of the proxy) invoke another methods on itself, it won't be invoked on the proxy so the AOP part will be bypassed. AspectJ doesn't have that limitation as it's modifying your classes, not just creating proxies around them. I would strongly suggest to go with AspectJ instead of Spring AOP. Spring will work great with AspectJ too.

Related

How to define a Pointcut to pick out all methods invoked by the specified method?

Is there any way to define a pointcut in AspectJ that would pick out each method directly executed by a specified method?
For example if there is a parentMethod() in classA that looks like:
public void parentMethod() {
classB.methodX();
classC.methodY();
}
I want to define a pointcut that uses just the information about parentMethod to pick out whenever its invoked methods, methodX() and methodY(), are executed. Is there a way to achieve this using AspectJ pointcuts?
I think we are not talking about inheritance, so you should not call it a "parent method". You simply mean a method calling other methods, do you not? Anyway, concerning your question:
With Spring AOP you have limited means of expressing control flow pointcuts, compared to native AspectJ's cflow() and cflowbelow() pointcuts. In your case and if you want to stick with proxy-based Spring AOP, a ControlFlowPointcut might be enough, because you do not need any method name patterns but seem to have a fixed method name as your target. For more information, see:
Section "update 2" of this answer for basic pointers to resources concerning ControlFlowPointcut.
This answer, if you want to match method patterns with a custom MultiMethodControlFlowPointcut (currently still unsupported by Spring out of the box).
Spring manual chapter "Using AspectJ with Spring Applications" explains how to configure Spring to use native AspectJ via load-time weaving (LTW).
If you decide to go the native AspectJ LTW way, the AspectJ manual section about control-flow-based pointcuts briefly explains cflow and cflowbelow.

Why is Spring's ApplicationContext.getBean with Interface considered bad? [duplicate]

I asked a general Spring question: Auto-cast Spring Beans and had multiple people respond that calling Spring's ApplicationContext.getBean() should be avoided as much as possible. Why is that?
How else should I gain access to the beans I configured Spring to create?
I'm using Spring in a non-web application and had planned on accessing a shared ApplicationContext object as described by LiorH.
Amendment
I accept the answer below, but here's an alternate take by Martin Fowler who discusses the merits of Dependency Injection vs. using a Service Locator (which is essentially the same as calling a wrapped ApplicationContext.getBean()).
In part, Fowler states, "With service locator the application class asks for it [the service] explicitly by a message to the locator. With injection there is no explicit request, the service appears in the application class - hence the inversion of control.
Inversion of control is a common feature of frameworks, but it's something that comes at a price. It tends to be hard to understand and leads to problems when you are trying to debug. So on the whole I prefer to avoid it [Inversion of Control] unless I need it. This isn't to say it's a bad thing, just that I think it needs to justify itself over the more straightforward alternative."
I mentioned this in a comment on the other question, but the whole idea of Inversion of Control is to have none of your classes know or care how they get the objects they depend on. This makes it easy to change what type of implementation of a given dependency you use at any time. It also makes the classes easy to test, as you can provide mock implementations of dependencies. Finally, it makes the classes simpler and more focused on their core responsibility.
Calling ApplicationContext.getBean() is not Inversion of Control! While it's still easy to change what implemenation is configured for the given bean name, the class now relies directly on Spring to provide that dependency and can't get it any other way. You can't just make your own mock implementation in a test class and pass that to it yourself. This basically defeats Spring's purpose as a dependency injection container.
Everywhere you want to say:
MyClass myClass = applicationContext.getBean("myClass");
you should instead, for example, declare a method:
public void setMyClass(MyClass myClass) {
this.myClass = myClass;
}
And then in your configuration:
<bean id="myClass" class="MyClass">...</bean>
<bean id="myOtherClass" class="MyOtherClass">
<property name="myClass" ref="myClass"/>
</bean>
Spring will then automatically inject myClass into myOtherClass.
Declare everything in this way, and at the root of it all have something like:
<bean id="myApplication" class="MyApplication">
<property name="myCentralClass" ref="myCentralClass"/>
<property name="myOtherCentralClass" ref="myOtherCentralClass"/>
</bean>
MyApplication is the most central class, and depends at least indirectly on every other service in your program. When bootstrapping, in your main method, you can call applicationContext.getBean("myApplication") but you should not need to call getBean() anywhere else!
Reasons to prefer Service Locator over Inversion of Control (IoC) are:
Service Locator is much, much easier for other people to following in your code. IoC is 'magic' but maintenance programmers must understand your convoluted Spring configurations and all the myriad of locations to figure out how you wired your objects.
IoC is terrible for debugging configuration problems. In certain classes of applications the application will not start when misconfigured and you may not get a chance to step through what is going on with a debugger.
IoC is primarily XML based (Annotations improve things but there is still a lot of XML out there). That means developers can't work on your program unless they know all the magic tags defined by Spring. It is not good enough to know Java anymore. This hinders less experience programmers (ie. it is actually poor design to use a more complicated solution when a simpler solution, such as Service Locator, will fulfill the same requirements). Plus, support for diagnosing XML problems is far weaker than support for Java problems.
Dependency injection is more suited to larger programs. Most of the time the additional complexity is not worth it.
Often Spring is used in case you "might want to change the implementation later". There are other ways of achieving this without the complexity of Spring IoC.
For web applications (Java EE WARs) the Spring context is effectively bound at compile time (unless you want operators to grub around the context in the exploded war). You can make Spring use property files, but with servlets property files will need to be at a pre-determined location, which means you can't deploy multiple servlets of the same time on the same box. You can use Spring with JNDI to change properties at servlet startup time, but if you are using JNDI for administrator-modifiable parameters the need for Spring itself lessens (since JNDI is effectively a Service Locator).
With Spring you can lose program Control if Spring is dispatching to your methods. This is convenient and works for many types of applications, but not all. You may need to control program flow when you need to create tasks (threads etc) during initialization or need modifiable resources that Spring didn't know about when the content was bound to your WAR.
Spring is very good for transaction management and has some advantages. It is just that IoC can be over-engineering in many situations and introduce unwarranted complexity for maintainers. Do not automatically use IoC without thinking of ways of not using it first.
It's true that including the class in application-context.xml avoids the need to use getBean. However, even that is actually unnecessary. If you are writing a standalone application and you DON'T want to include your driver class in application-context.xml, you can use the following code to have Spring autowire the driver's dependencies:
public class AutowireThisDriver {
private MySpringBean mySpringBean;
public static void main(String[] args) {
AutowireThisDriver atd = new AutowireThisDriver(); //get instance
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"/WEB-INF/applicationContext.xml"); //get Spring context
//the magic: auto-wire the instance with all its dependencies:
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(atd,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
// code that uses mySpringBean ...
mySpringBean.doStuff() // no need to instantiate - thanks to Spring
}
public void setMySpringBean(MySpringBean bean) {
this.mySpringBean = bean;
}
}
I've needed to do this a couple of times when I have some sort of standalone class that needs to use some aspect of my app (eg for testing) but I don't want to include it in application-context because it is not actually part of the app. Note also that this avoids the need to look up the bean using a String name, which I've always thought was ugly.
One of the coolest benefits of using something like Spring is that you don't have to wire your objects together. Zeus's head splits open and your classes appear, fully formed with all of their dependencies created and wired-in, as needed. It's magical and fantastic.
The more you say ClassINeed classINeed = (ClassINeed)ApplicationContext.getBean("classINeed");, the less magic you're getting. Less code is almost always better. If your class really needed a ClassINeed bean, why didn't you just wire it in?
That said, something obviously needs to create the first object. There's nothing wrong with your main method acquiring a bean or two via getBean(), but you should avoid it because whenever you're using it, you're not really using all of the magic of Spring.
The motivation is to write code that doesn't depend explicitly on Spring. That way, if you choose to switch containers, you don't have to rewrite any code.
Think of the container as something is invisible to your code, magically providing for its needs, without being asked.
Dependency injection is a counterpoint to the "service locator" pattern. If you are going to lookup dependencies by name, you might as well get rid of the DI container and use something like JNDI.
Using #Autowired or ApplicationContext.getBean() is really the same thing. In both ways you get the bean that is configured in your context and in both ways your code depends on spring.
The only thing you should avoid is instantiating your ApplicationContext. Do this only once! In other words, a line like
ApplicationContext context = new ClassPathXmlApplicationContext("AppContext.xml");
should only be used once in your application.
One of Spring premises is avoid coupling. Define and use Interfaces, DI, AOP and avoid using ApplicationContext.getBean() :-)
One of the reasons is testability. Say you have this class:
interface HttpLoader {
String load(String url);
}
interface StringOutput {
void print(String txt);
}
#Component
class MyBean {
#Autowired
MyBean(HttpLoader loader, StringOutput out) {
out.print(loader.load("http://stackoverflow.com"));
}
}
How can you test this bean? E.g. like this:
class MyBeanTest {
public void creatingMyBean_writesStackoverflowPageToOutput() {
// setup
String stackOverflowHtml = "dummy";
StringBuilder result = new StringBuilder();
// execution
new MyBean(Collections.singletonMap("https://stackoverflow.com", stackOverflowHtml)::get, result::append);
// evaluation
assertEquals(result.toString(), stackOverflowHtml);
}
}
Easy, right?
While you still depend on Spring (due to the annotations) you can remove you dependency on spring without changing any code (only the annotation definitions) and the test developer does not need to know anything about how spring works (maybe he should anyway, but it allows to review and test the code separately from what spring does).
It is still possible to do the same when using the ApplicationContext. However then you need to mock ApplicationContext which is a huge interface. You either need a dummy implementation or you can use a mocking framework such as Mockito:
#Component
class MyBean {
#Autowired
MyBean(ApplicationContext context) {
HttpLoader loader = context.getBean(HttpLoader.class);
StringOutput out = context.getBean(StringOutput.class);
out.print(loader.load("http://stackoverflow.com"));
}
}
class MyBeanTest {
public void creatingMyBean_writesStackoverflowPageToOutput() {
// setup
String stackOverflowHtml = "dummy";
StringBuilder result = new StringBuilder();
ApplicationContext context = Mockito.mock(ApplicationContext.class);
Mockito.when(context.getBean(HttpLoader.class))
.thenReturn(Collections.singletonMap("https://stackoverflow.com", stackOverflowHtml)::get);
Mockito.when(context.getBean(StringOutput.class)).thenReturn(result::append);
// execution
new MyBean(context);
// evaluation
assertEquals(result.toString(), stackOverflowHtml);
}
}
This is quite a possibility, but I think most people would agree that the first option is more elegant and makes the test simpler.
The only option that is really a problem is this one:
#Component
class MyBean {
#Autowired
MyBean(StringOutput out) {
out.print(new HttpLoader().load("http://stackoverflow.com"));
}
}
Testing this requires huge efforts or your bean is going to attempt to connect to stackoverflow on each test. And as soon as you have a network failure (or the admins at stackoverflow block you due to excessive access rate) you will have randomly failing tests.
So as a conclusion I would not say that using the ApplicationContext directly is automatically wrong and should be avoided at all costs. However if there are better options (and there are in most cases), then use the better options.
The idea is that you rely on dependency injection (inversion of control, or IoC). That is, your components are configured with the components they need. These dependencies are injected (via the constructor or setters) - you don't get then yourself.
ApplicationContext.getBean() requires you to name a bean explicitly within your component. Instead, by using IoC, your configuration can determine what component will be used.
This allows you to rewire your application with different component implementations easily, or configure objects for testing in a straightforward fashion by providing mocked variants (e.g. a mocked DAO so you don't hit a database during testing)
Others have pointed to the general problem (and are valid answers), but I'll just offer one additional comment: it's not that you should NEVER do it, but rather that do it as little as possible.
Usually this means that it is done exactly once: during bootstrapping. And then it's just to access the "root" bean, through which other dependencies can be resolved. This can be reusable code, like base servlet (if developing web apps).
There is another time when using getBean makes sense. If you're reconfiguring a system that already exists, where the dependencies are not explicitly called out in spring context files. You can start the process by putting in calls to getBean, so that you don't have to wire it all up at once. This way you can slowly build up your spring configuration putting each piece in place over time and getting the bits lined up properly. The calls to getBean will eventually be replaced, but as you understand the structure of the code, or lack there of, you can start the process of wiring more and more beans and using fewer and fewer calls to getBean.
I've only found two situations where getBean() was required:
Others have mentioned using getBean() in main() to fetch the "main" bean for a standalone program.
Another use I have made of getBean() are in situations where an interactive user configuration determines the bean makeup for a particular situation. So that, for instance, part of the boot system loops through a database table using getBean() with a scope='prototype' bean definition and then setting additional properties. Presumably, there is a UI that adjusts the database table that would be friendlier than attempting to (re)write the application context XML.
however, there are still cases where you need the service locator pattern.
for example, i have a controller bean, this controller might have some default service beans, which can be dependency injected by configuration.
while there could also be many additional or new services this controller can invoke now or later, which then need the service locator to retrieve the service beans.
You should to use: ConfigurableApplicationContext instead of for ApplicationContext

Why in Spring AOP the object are wrapped into a JDK proxy that implements interfaces?

I am studying Spring and I have the followig
Consider the following bean definition:
<bean id="clientService" class="com.myapp.service.ClientServiceImpl" />
Now consider the case on which it is declared a pointcut* targetting all methods inside the **clientService bean.
Consider also that the ClientServiceImpl class implements 3 interfaces
Now I know that using AOP the clientService bean is proxied and that this proxy implements all the 3 interfaces.
But what is the exact reason for which all these 3 interface are implemented?
So it seems to me that exist 2 kinds of proxies (correct me if I am saying wrong assertions):
JDK Proxy: used by default from Spring (is it true?) in wicht I have an interface that define the method of the object that I want to proxify. So the concrete implementation of this interface is wrapped by the proxy. So when I call a method on my object I am calling it on its proxy. The call is recognized by a method interceptor that eventually perform the aspect and then is performed the invoked method.
CGLIB Proxy: in wich, it seems to me that, the proxy extend the implementation of the wrapped object adding to it the extra logic features
Something like this:
So it seems to me that Spring use the first kind of proxy that is based on the implementation of interfaces (is it right?):
I think that in AOP the extra logic is represented by the implementation of the method interceptor (is it true?) and the standard logic is represented by the implementation of the method defined into the interfaces.
But, if the previous reasoning are correct, my doubts is: why I need to define these interface and do that the object wrapped by the object implement these interfaces? (I can't understand if the proxy itself implement these interfaces).
Why? How exactly works?
Tnx
But what is the exact reason for which all these 3 interface are
implemented?
If the proxy didn't implement all of those interfaces, the bean couldn't be wired into other beans that use that interface (you'd get a ClassCastException). For example, autowiring all of the beans of that interface into a bean. Additionally, things like getBeanNamesForType wouldn't work if the proxy didn't implement the interface.
So it seems to me that exist 2 kinds of proxies (correct me if I am
saying wrong assertions)
Yes that's correct. See ScopedProxyMode. By default, Spring won't create a proxy. It only creates a proxy if it needs to wrap the bean to add additional behavior (AOP). Note that there's also a special case of the CGLIB based proxy that uses Objenesis to deal with subclassing targets that don't have a default constructor.
CGLIB Proxy: in wich, it seems to me that, the proxy extend the
implementation of the wrapped object adding to it the extra logic
features
When you use CGLIB based proxies, the constructor for your bean gets called twice: once when the dynamically generated subclass is instantiated (to create the proxy) and a second time when the actual bean is created (the target).
I think that in AOP the extra logic is represented by the
implementation of the method interceptor (is it true?)
The proxy is essentially just invoking the chain of advice needs to be applied. That advice isn't implemented in the proxy itself. For example, the advice for #Transactional lives in TransactionAspectSupport. Take a look at the source to JdkDynamicAopProxy.
and the standard logic is represented by the implementation of the
method defined into the interfaces.
Assuming that you're programming against interfaces and using JDK proxies that's correct.
But, if the previous reasoning are correct, my doubts is: why I need
to define these interface and do that the object wrapped by the object
implement these interfaces? (I can't understand if the proxy itself
implement these interfaces).
If you want to use interface based proxies you need to use interfaces. Just make sure all of your beans implement interfaces, all of your advised methods are defined by those interfaces, and that when one bean depends on another bean, that dependency is specified using an interface. Spring will take care of constructing the proxy and making sure it implements all of the interfaces.
In your diagram, you have "Spring AOP Proxy (this)". You have to be really careful with using this when you're using any type of proxying.
Calls within the same class won't have advice applied because those calls won't pass through the proxy.
If in one of your beans you pass this to some outside code, you're passing the target of the AOP advice. If some other code uses that reference, the calls won't have AOP advice applied (again, you're bypassing the proxy).

Implementing an interface from a framework vs simple java interface

This concept is unclear with me.
I have worked on several frameworks for an instance Spring.
To implement a feature we always implement some interfaces provided by the framework.
For an instance if I have to create a custom scope in Spring, my class implements a org.springframework.beans.factory.config.Scope interface. Which has some predefined low level functionality which helps in defining a custom scope for a bean.
Whereas in Java I read an interface is just a declaration which classes can implement & define their own functionality. The methods of an interface have no predefined functionality.
interface Car
{
topSpeed();
acclerate();
deaccelrate();
}
The methods here don't have any functionality. They are just declared.
Can anyone explain this discrepancy in the concept? How does the framework put some predefined functionality with interface methods?
It doesn't put predefined functionality in the methods. But when you implement
some interface (say I) in your class C, the framework knows that your object (of type C)
implements the I interface, and can call certain methods (defined in I) on your object
thus sending some signals/events to your object. These events can be e.g. 'app initialized',
'app started', 'app stopped', 'app destroyed'. So usually this is what frameworks do.
I am talking about frameworks in general here, not Spring in particular.
There is no conceptual difference, actually. Each java interface method has a very clear responsibility (usually described in its javadoc). Take Collection.size() as an example. It is defined to return the number of elements in your collection. Having it return a random number is possible, but will cause no end of grief for any caller. Interface methods have defined semantics ;)
As I mentioned in the comments, to some extent, implementing interfaces provided by the framework is replaced by the use of stereotype annotations. For example, you might annotate a class as #Entity to let Spring know to manage it and weave a Transaction manager into it.
I have a suspicion that what you are seeing relates to how Spring and other frameworks make use of dynamic proxies to inject functionality.
For an example of Spring injecting functionality, if you annotate a method as #Transactional, then the framework will attempt to create a dynamic proxy, which wraps access to your method. i.e. When something calls your "save()" method, the call is actually to the proxy, which might do things like starting a transaction before passing the call to your implementation, and then closing the transaction after your method has completed.
Spring is able to do this at runtime if you have defined an interface, because it is able to create a dynamic proxy which implements the same interface as your class. So where you have:
#Autowired
MyServiceInterface myService;
That is injected with SpringDynamicProxyToMyServiceImpl instead of MyServiceImpl.
However, with Spring you may have noticed that you don't always need to use interfaces. This is because it also permits AspectJ compile-time weaving. Using AspectJ actually injects the functionality into your class at compile-time, so that you are no longer forced to use an interface and implementation. You can read more about Spring AOP here:
http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#aop-introduction-defn
I should point out that although Spring does generally enable you to avoid defining both interface and implementation for your beans, it's not such a good idea to take advantage of it. Using separate interface and implementation is very valuable for unit testing, as it enables you to do things like inject a stub which implements an interface, instead of a full-blown implementation of something which needs database access and other rich functionality.

Factory class vs Spring DI

As per my understanding both Factory class and Spring DI follows the Dependency injection. I mean in both the cases external entity is used to push the dependency. Right?
My question is which one i should go for between factory classes and Spring DI when my intention is just to get the objects . Assume i don't want any other features like aop, dao support etc. Only purpose is to get the objects either from Factory class or Spring DI. Which one is preferable.
on some site read this statement
DI loosely coupled and less intrusive in comparison to Factory classes
But could not get how spring DI loosely coupled and less intrusive than factory classes?
in both the cases we have to insert some kind of get object code in our core program .
Spring DI promotes loosely coupled code because the Spring container injects your dependencies based on configuration. If you are injecting interface implementations, you don't have to change code to change which specific implementation gets injected, unless you consider your configuration code, which many do.
If you use a Factory to create configured objects that are used by the rest of your code, you are writing code to create the objects, configure them, etc. If you want to change what the factory returns, you have to change actual code, which some would argue is a more intrusive change.
Typically Spring is used to configure how the various layers of your application are wired together. X service takes such and such DAO implementations, for example. That's application level organization. Lets say you have a scenario where want to create a button for every row in a list -- in that case you could use a factory to create the buttons. This scenario is based on a runtime situation where the GUI has different elements that you couldn't configure up front (because its based on the data), so DI makes less sense here.
EDIT - based on your comment questions, I think the primary point here is that you have to consider is that Spring is also an Inversion of Control container. That means you don't program in which components in your application go where. Without IoC, you might do something like
MyServiceImpl extends MyService {
Dao1 = new Dao1Impl(); // you programmatically configure which components go in here
Dao2 = new Dao2Impl();
....
}
instead you do something like
MyServiceImpl extends MyService {
public Dao1; // you haven't specified which components, only interfaces
public Dao2;
....
}
In the second code sample, Spring (or whatever you use) will inject the appropriate DAO instances for you. You have moved control of which components to use to a higher level. So IoC and DI go hand and hand, IoC promotes loose coupling because in your component definitions (i.e. interfaces) you only specify behavior.
In other words, IoC and DI are not necessary for loose coupling; you can have loose coupling with a Factory too
MyServiceImpl extends MyService {
public dao1
public dao2;
MyServiceImpl(){
dao1 = DaoFactory.getDao1();
...
}
....
}
here your service still only depends on DAO definitions and you use the factory to get implementations. The caveat is that your service is now coupled to the factory. You can make it more loose by passing a Factory into your constructor if you want....
Also, dont forget that Spring provides other useful functionalities, like its transaction management. That's incredibly helpful, even though you said for your app you don't need it.
But could not get how spring DI loosely coupled and less intrusive
than factory classes? in both the cases we have to insert some kind of
get object code in our core program .
Spring makes it less intrusive because it uses reflection to automatically "inject/create" the dependencies. Thus your code does not need a reference to a the factory.
Spring is generally used for "Singleton-like" object creation. People generally use custom factories for transient throw away object creation (like request objects).
In fact often times you will make Spring create and inject your custom factories (ie factory of a factory).

Categories

Resources