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.

Install jdk 8 in Yosemite 10.10.2

While i was trying to downgrade JDK from 1.8.0._25 to 1.8.0_05 into the yosemite 10.10.2 so that i could use the DCEVM in my OSX.

 

I first remove the new version by just do a

sudo mv jdk1.8.0_25.jdk ~/Desktop/

Next step is to install the 1.8.0_05 which is the current latest version that DCEVM supports.However, I got the following error:

Your system has Mac OS X Version 10.10.2. This product can be installed on Version 10.7.3 or later.
Visit java.com/help for more information. 

Logically it looks really weird since apparently 10.10.2 is later than the 10.7.3. I think what they do is just compare the first digit so 1<7.

To install this, I have to spoof the OSX version.

1. go to  /System/Library/CoreServices and find the SystemVersion.plist which from its name we know contains the system version.

2. if you try to edit it directly you will find it r–r–r– readonly. To change it, you can either chmod it to 777 and modify content, or open it with some textEditor and do save as the same file name and extension. Then copy it back to the directory.

3. You can modify the version number to 9001 which is obviously larger than 10.10.1. I suggest you modify both ProductVersion and ProductUserVisibleVersion so that you could go to the “about this Mac” to verify the change.

4. Now you should be able to install without that error.

5. Do remember to change it back to whatever version you were before the modification.

 

关于jdk和jre

大家肯定在安装JDK的时候会有选择是否安装单独的jre,一般都会一起安装,我也建议大家这样做。因为这样更能帮助大家弄清楚它们的区别:

Jre 是java runtime environment, 是java程序的运行环境。既然是运行,当然要包含jvm,也就是大家熟悉的虚拟机啦,还有所有java类库的class文件,都在lib目录下打包成了jar。大家可以自己验证。至于在windows上的虚拟机是哪个文件呢?学过MFC的都知道什么是dll文件吧,那么大家看看jre/bin/client里面是不是有一个jvm.dll呢?那就是虚拟机。

Jdk 是java development kit,是java的开发工具包,里面包含了各种类库和工具。当然也包括了另外一个Jre. 那么为什么要包括另外一个Jre呢?而且jdk/jre/bin同时有client和server两个文件夹下都包含一个jvm.dll。说明是有两个虚拟机的。这一点不知道大家是否注意到了呢?

相信大家都知道jdk的bin下有各种java程序需要用到的命令,与jre的bin目录最明显的区别就是jdk下才有javac,这一点很好理解,因为 jre只是一个运行环境而已。与开发无关,正因为如此,具备开发功能的jdk自己的jre下才会同时有client性质的jvm和server性质的 jvm, 而仅仅作为运行环境的jre下只需要client性质的jvm.dll就够了。

记得在环境变量path中设置jdk/bin路径麽?这应该是大家学习Java的第一步吧,老师会告诉大家不设置的话javac和java是用不了的。确实jdk/bin目录下包含了所有的命令。可是有没有人想过我们用的java命令并不是 jdk/bin目录下的而是jre/bin目录下的呢?不信可以做一个实验,大家可以把jdk/bin目录下的java.exe剪切到别的地方再运行 java程序,发现了什么?一切OK!

那么有人会问了?我明明没有设置jre/bin目录到环境变量中啊?

试想一下如果java为了提供给大多数人使用,他们是不需要jdk做开发的,只需要jre能让java程序跑起来就可以了,那么每个客户还需要手动去设置环境变量多麻烦啊?所以安装jre的时候安装程序自动帮你把jre的java.exe添加到了系统变量中,验证的方法很简单,大家看到了系统环境变量的 path最前面有“%SystemRoot%system32;%SystemRoot%;”这样的配置,那么再去Windows/system32下面去看看吧,发现了什么?有一个java.exe。

如果强行能够把jdk/bin挪到system32变量前面,当然也可以迫使使用jdk/jre里面的java,不过除非有必要,我不建议大家这么做。使用单独的jre跑java程序也算是客户环境下的一种测试。

当在控制台执行java.exe,操作系统寻找JRE的方式如下:

先找当前目录下有没有JRE
再找父目录下有没有JRE
接着在PATH路径中找JRE(一般运行时从path中查找,按照path设置前后顺序,以前面为准)
注册表HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\ 查看CurrentVersion的键值指向哪个JRE(一般XP下是这个:C:\Program Files\Java\jre6)

最常用的是在PATH路径中找JRE,一般情况下,自己的程序运行之前都会先在批处理文件里面临时设置PATH,把自己用的JRE放到PATH路径最前面,所以肯定会运行自己带的JRE,不会造成版本混乱。

最容易的试验方法就是到不同的jre/bin的目录下去执行java -version, 就可以看到不同的版本。在其他地方执行的话都是public的那个JRE

FROM HERE AND HERE

CentOS Linux VPS搭建Java环境

搭建Java环境要安装JDK,搭配Tomcat可以作为JSP Web服务器。系统先升级到目前最新。

yum check-update && yum update

安装软件说明:
JRE(Java Runtime Enviroment)是Java运行环境,JDK(Java Development Kit)是Java开发环境,包括了Java开发工具、Java运行环境、及其它工具。
Java SE(standard edition)是标准版,Java EE(enterprise edition)是企业版,Java ME(micro edition)是用于移动和嵌入式设备。

这里JDK安装的是Java SE 6:
JDK下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html
支持rpm包的linux系统下载jdk-6u27-linux-i586-rpm.bin,不支持RPM包的如Debian下载jdk-6u27-linux-i586.bin。

开始安装:

cd /tmp
wget http://download.oracle.com/otn-pub/java/jdk/6u27-b07/jdk-6u27-linux-i586-rpm.bin
chmod a+x jdk-6u27-linux-i586-rpm.bin
./jdk-6u27-linux-i586-rpm.bin

安装的路径为/usr/java/jdk1.6.0_27,编辑环境变量:

vim /etc/profile

在最后加入:

export JAVA_HOME=/usr/java/jdk1.6.0_27
export CALSSPATH=$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin

重启系统:

reboot

安装Tomcat,这里下的是已经编译好的Binary Distributions:

cd /tmp
wget http://labs.renren.com/apache-mirror/tomcat/tomcat-6/v6.0.33/bin/apache-tomcat-6.0.33.tar.gz
tar -zxvf apache-tomcat-6.0.33.tar.gz
mv apache-tomcat-6.0.33 /usr/local/tomcat

编辑tomcat jvm启动参数:

vim /usr/local/tomcat/bin/catalina.sh

在cygwin=false前加入:

JAVA_OPTS=”-Xms32m -Xmx64m -Xss128K -XX:PermSize=16m -XX:MaxPermSize=32m”

启动tomcat:

/usr/local/tomcat/bin/startup.sh

访问:

http://IP:8080,出现tomcat默认页面说明成功。