Spring proxy jdk vs cglib

Simple version:

Aspectj static weaving: do the aop at compile time using Aspectj’s own compiler: ajc.

JDK Proxy: when class implements some interface. The proxy will implement every interface. It can NOT be cast to the original target class because it’s simply a dynamic proxy that happens to implement the same interface(s) as the target

CGLIB: When class is concrete without any interface. The proxy will subclass the target.

Note: the JDK-proxy and CGLIB is transparent to the user.

Less simple version

超详细中文版

1. What proxies Spring uses?

There are two types of proxies available:

JDK proxy, which is comes out of the box in JDK and CGLib, which is created by the CGLib library (3rd party dependency).

JDK Proxy only works with beans that implement an interface (which in my view is a good thing, you should code to intreface not concrete classes) and it is also the Spring recommended way of using AOP.

Quote from Spring doc:

As it is good practice to program to interfaces rather than classes, business classes normally will implement one or more business interfaces.

However, there are lots of people out there who like to code concrete classes and therefore must use CGLib. This means that there should be a cglib.jar on classpath to make it work and there is also a side effect whereby your proxy constructors will run twice – so use constructors only for dependency injection (no business logic allowed)

2. How does spring AOP knows what proxy to use?

Configuration mostly come from <aop:config/>, <tx:annotation-driven/>, <aop:aspectj-autoproxy/> and <aop:scoped-proxy/> as well as some configurable properties on some factory beans.

The important thing to remember is that some of these configs are merged before being processed.

Quote from Spring doc:

Multiple <aop:config/> sections are collapsed into a single unified auto-proxy creator at runtime, which applies the strongest proxy settings that any of the <aop:config/> sections (typically from different XML bean definition files) specified. This also applies to the <tx:annotation-driven/> and <aop:aspectj-autoproxy/> elements.
To be clear: using ‘ proxy-target-class=”true”‘ on <tx:annotation-driven/>, <aop:aspectj-autoproxy/> or <aop:config/> elements will force the use of CGLIB proxies for all three of them.

So be careful when defining these tags in multiple xml configuration files.

Now in order to enforce JDK proxy the following configuration must be used: <aop:config proxy-target-class=”false”>

Example:

    &lt;aop:config proxy-target-class="false"&gt;
        &lt;aop:advisor advice-ref="runtimeCacheAdvice" pointcut="execution(* com..ErpRuntimeContextInternal.providePreferences(..))"&gt;
...
    &lt;/aop:advisor&gt;&lt;/aop:config&gt;

Make sure that all of config tags have the proxy-target-class set to false. However this does not affect the TransactionProxyFactoryBean (if you are using ORM)

In order to use JDK proxies for your transactional beans you must set proxyTargetClass property to false.

Example:

&lt;bean id="txSecurityProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&gt;
    &lt;description&gt;
        NOTE: see org.springframework.transaction.TransactionDefinition
        disable transactions by default (bean must explicitly specify)
    &lt;/description&gt;
    &lt;property name="transactionManager" ref="transactionManager"&gt;
    &lt;property name="proxyTargetClass" value="false"&gt;
    &lt;property name="transactionAttributes"&gt;
        &lt;props&gt;
            &lt;prop key="*"&gt;PROPAGATION_NOT_SUPPORTED&lt;/prop&gt;
        &lt;/props&gt;
    &lt;/property&gt;
&lt;/property&gt;&lt;/property&gt;&lt;/bean&gt;

For CGlib the corresponding proxyTargetClass and proxy-target-class should be set to true.

As you may have noticed I use XML configuration for Spring and some people may find it ancient approach suitable only for those who like the Flinstones. However, my view is that annotations polute your code because they are directly applied to your classes. Image if you use Spring annotations, The some JPA, then some JAXB then some other 3rd party libraries annotation – it is a complete mess! With XML you create POJO’s and then define separate XML configurations for your application concerns like: ORM, DTO, Spring, cache and so on. Moreover each of these confiurations can be changes without touching the code. So I think it is much better from the SOLID point of view. (and yes I did enjoy the Flinstones, so there). But if you are a big fan of annotations I am sure you can google for the corresponding configs.

3. Now that you now everything – or do you?

Now you may think that you know everything and you got your app working like you want – think again! In what order do your aspects execute?

Yes, if you have transactions and then ehcache and then some performance logging you may have several proxies! So you need to order them so that you know precisely when and if your aspects get executed. Use the order attribute.

Example:

 
    &lt;aop:config proxy-target-class="false"&gt;
        &lt;aop:advisor advice-ref="runtimeCacheAdvice" order="100" pointcut="execution(* com..ErpRuntimeContextInternal.providePreferences(..))"&gt;
...
    &lt;/aop:advisor&gt;&lt;/aop:config&gt;
So now hopefully you get the bigger picture of how AOP works in Spring and major gotchas that you may encounter.

FROM HERE

Another link about getting object behind the proxy.

Advertisements

could not initialize proxy – no Session

All java web frameworks have one or more servlets that handle the requests. The servlet handles each request (HttpRequest) by creating a new thread that will finally produce the response (HttpResponse). The method that processes each request is executed inside this thread.

At the beginning of the request processing your application should allocate the resources that it needs for processing (Transaction, Hibernate session etc). At the end of the processing cycle these resources are released (Transaction is committed, hibernate session is closed, JDBC connections are released etc). Lifecycle of these resources could be managed by your framework, or could be done by your code.

In order to support application state in a stateless protocol as HTTP, we have the HttpSession object. We (or the frameworks) put on HttpSession the information that remains relevant between different request cycles of the same client.

During the processing of the first request hibernate reads (lazily) an entity from the database. Due to lazy initialization some parts of this object’s structure are hibernate proxy objects. These objects are associated with the hibernate session that created them.

When you try to process the second request, then the framework finds the entity from the previous request in the HttpSession object. Then it is trying to access a property from a child entity that was lazily initialized and now is a hibernate proxy object. The hibernate proxy object is an imitation of the real object that will ask its hibernate session to fill it with information from the database when someone tries to access one of its properties. This what your hibernate proxy is trying to do. But its session was closed at the end of the previous request processing, so now it doesn’t have a hibernate session to use in order to be hydrated (filled with real info).

Note that it is possible that you have already opened a hibernate session at the beginning of the second request, but it isn’t aware of the entity that contains the proxy object because this entity was read by a different hibernate sesion. You should re-attach the entity to the new hibernate session.

There is a lot of discussion about how to re-attach a detached entity, but the simplest approach right now is session.update(entity).

I solved the problem by annotating the method which indirectly uses Hibernate to retrieve data from the database with @Transactional.

 

Good reference on session and transaction

another post

Hibernate lazy loading

Hibernate uses a proxy object to support lazy loading. Basically as soon as you reference a child or lookup object via the accessor/getter methods, if the linked entity is not in the session cache (i.e. the first-level cache), then the proxy code will go off to the database and load the linked object. It uses javassist (or CGLIB ) to effectively and dynamically generate sub-classed implementations of your objects.

Let’s look at an example. An employee hierarchy table can be represented in a database table as shown below

1
2
3
4
5
6
7
8
9
10
11
public class Employee {
   private Long id;
   private String name;
   private String title;
   private Employee superior;
   private Set<Employee> subordinates;
   //getters and setters are omitted
}

In the above example, if you use lazy loading then the “superior” and “subordinates” will be proxied (i.e. not the actual object, but the stub object that knows how to load the actual object) when the main “Employee” object is loaded. So, if you need to get the “subordinates” or “superior” object, you invoke the getter method on the employee likeemployee.getSuperior( ) and the actual object will be loaded.

 

FROM HERE

Using hibernate with GWT

We can not use DAO objects directly for GWT RPC even you implement the IsSerializable or Serializable interface.

When you take an object and turn it into a Hibernate object, the object is now enhanced to be persistent. That persistence does not come without some type of instrumentation of the object. In the case of Hibernate, the Javassist library actually replaces and rewrites the bytecode for these objects by persistent entities to make the Hibernate magic work. What this means for GWT RPC is that by the time the object is ready to be transferred over the wire, it actually isn’t the same object that the compiler thought was going to be transferred, so when trying to deserialize, the GWT RPC mechanism no longer knows what the type is and refuses to deserialize it.

As a result, the DTO comes in.

We create pojos for those DAOs and create bi-direction tranfer methods for DAO and DTO.

Another way is to deproxy the object from hibernate lazy loading:

one of the side effects of Hibernate lazy loading: In order to allow lazy access to any relational objects, Hibernate returns a “proxy” object that essentially wraps and mimics the object that you wanted. This way when you call a getter, instead of throwing a NullPointerException, Hibernate can retrieve the result from the database.

Great… so what now? While the proxy object will suffice whenever you need to access a public property or method, it quickly becomes apparent that introspection and reflection present a problem. Since the proxy object is not truly an instance of the class that it is wrapping, metadata (such as annotations) are not there.


@Aspect
public class HibernateProxyUtil {

@Around("@within(DeProxy) || @annotation(DeProxy)")
 public <T> T initializeAndUnproxy(ProceedingJoinPoint pjp) throws Throwable {
 T entity = (T) pjp.proceed();
 if (entity == null) {
 return null;
 }

Hibernate.initialize(entity);
 if (entity instanceof HibernateProxy) {
 entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
 }
 return entity;
 }
}

In addition we specify this class in our applicationContext xml then we can use @Deproxy for our service layer class.

<aop:aspectj-autoproxy/>

<bean id=”deProxyAspect” class=”org.finra.cdip.cobra.server.util.HibernateProxyUtil”/>

git http proxy

Have to use proxy to check out code from github since I am in the company’s network.

The way is:

// Set proxy for git globally
 git config --global http.proxy http://proxy:8080
// To check the proxy settings
git config --get http.proxy
// Just in case you need to you can also revoke the proxy settings
git config --global --unset http.proxy

Subversion with Eclipse using proxy

For Subclipse plugin proxy setting  in eclipse

You need to open

C:\Documents and Settings\<user_name>\Application Data\Subversion\servers

 

Note: for windows 7 this could also be found in

c:\Users\<user_name>\AppData\<Roaming\Local>\Subversion\servers

In this file you need to uncomment few line under global

[global]

# http-proxy-host=proxy1.some-domain-name.com
# http-proxy-port=80
# http-proxy-username=blah
# http-proxy-password=doubleblah
# http-timeout=60