SSLSocket Java Part3

1、SSLSocket Client绕过证书检查

package com.ats.ssl.socket;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class ClientWithTrustManager {
	
	public static void connectAndSend(String trustStorePath,
			String trustStorePwd, String ip, int port, String msg) throws IOException, NoSuchAlgorithmException, KeyManagementException{
        
		SSLContext sslContext = SSLContext.getInstance("TLS");
		//SSLContext sslContext = SSLContext.getInstance("SSLv3");
		sslContext.init(new KeyManager[0], new TrustManager[] { new DefaultTrustManager() }, new SecureRandom());
		SSLContext.setDefault(sslContext);
		
		SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();  
		SSLSocket sslsocket = (SSLSocket) sslSocketFactory.createSocket(
				"localhost", 9999);

		try {
			OutputStream outputstream = sslsocket.getOutputStream();
			OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
					outputstream);
			BufferedWriter bufferedwriter = new BufferedWriter(
					outputstreamwriter);

			bufferedwriter.write(msg);
			bufferedwriter.flush();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			sslsocket.close();
		}
	}

	private static class DefaultTrustManager implements X509TrustManager {

		@Override
		public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
		}

		@Override
		public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
		}

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
	}
	
	public static void main(String[] args) throws Exception {
		try {
			URL url = Server.class.getClassLoader().getResource(
					"myTrustStore.jks");
			String jks = url.getFile();

			connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
					"This msg is from Java SSL Client :)");

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

SSLSocket Java Part2

1、SSLSocket Java Server使用SSLContext

package com.ats.ssl.socket;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class ServerWithContext {

	static String delimiter = "=========================================================";

	public static void startListen(String keyStorePath, String keyStorePwd, int port) throws IOException, KeyStoreException, NoSuchAlgorithmException,
			CertificateException, UnrecoverableKeyException, KeyManagementException {

		KeyStore keyStore = KeyStore.getInstance("JKS");
		keyStore.load(new FileInputStream(keyStorePath), keyStorePwd.toCharArray());
		KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
		keyManagerFactory.init(keyStore, keyStorePwd.toCharArray());

		//SSLContext sslContext = SSLContext.getInstance("TLSv1");
		SSLContext sslContext = SSLContext.getInstance("SSLv3");
		sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[0], null);

		SSLServerSocketFactory sslserversocketfactory = sslContext.getServerSocketFactory();
		SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);

		while (true) {
			SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

			DisplaySecurityLevel(sslsocket);
			DisplayCertificateInformation(sslsocket);

			try {
				InputStream inputstream = sslsocket.getInputStream();
				InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
				BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

				System.out.println(delimiter);
				String string = null;
				while ((string = bufferedreader.readLine()) != null) {
					System.out.println(string);
					System.out.flush();
				}
				System.out.println(delimiter);
			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				sslsocket.close();
			}
		}
	}

	static void DisplaySecurityLevel(SSLSocket sslsocket) {
		System.out.println(delimiter);
		SSLSession session = sslsocket.getSession();
		System.out.println("通讯协议: " + session.getProtocol());
		System.out.println("加密方式: " + session.getCipherSuite());
		System.out.println(delimiter);
	}

	static void DisplayCertificateInformation(SSLSocket sslsocket) {
		System.out.println(delimiter);
		Certificate[] localCertificates = sslsocket.getSession().getLocalCertificates();
		if (localCertificates == null || localCertificates.length == 0) {
			System.out.println("本地证书为空");
		} else {
			Certificate cert = localCertificates[0];
			System.out.println("本地证书类型: " + cert.getType());
			if (cert.getType().equals("X.509")) {
				X509Certificate x509 = (X509Certificate) cert;
				System.out.println("本地证书签发者: " + x509.getIssuerDN());
				System.out.println("本地证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
			}
		}

		try {
			Certificate[] peerCertificates = sslsocket.getSession().getPeerCertificates();

			if (peerCertificates == null || peerCertificates.length == 0) {
				System.out.println("远程证书为空");
			} else {
				Certificate cert = peerCertificates[0];
				System.out.println("远程证书类型: " + cert.getType());
				if (cert.getType().equals("X.509")) {
					X509Certificate x509 = (X509Certificate) cert;
					System.out.println("远程证书签发者: " + x509.getIssuerDN());
					System.out.println("远程证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
				}
			}
		} catch (SSLPeerUnverifiedException e) {
			// e.printStackTrace();
			System.out.println("远程证书为空");
		}

		System.out.println(delimiter);
	}

	public static void main(String[] arstring) {
		try {
			URL url = ServerWithContext.class.getClassLoader().getResource("myKeyStore.jks");
			String jks = url.getFile();
			startListen(jks, "sslTestPwd", 9999);

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

2、SSLSocket Java Client使用SSLContext

package com.ats.ssl.socket;

import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

public class ClientWithContext {
	
	public static void connectAndSend(String trustStorePath,
			String trustStorePwd, String ip, int port, String msg) throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException, UnrecoverableKeyException{
	
		KeyStore trustStore = KeyStore.getInstance("JKS");
		trustStore.load(new FileInputStream(trustStorePath), trustStorePwd.toCharArray());
		TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
		trustManagerFactory.init(trustStore);
        
		SSLContext sslContext = SSLContext.getInstance("TLSv1");
		//SSLContext sslContext = SSLContext.getInstance("SSLv3");
		
		sslContext.init(new KeyManager[0], trustManagerFactory.getTrustManagers(), null);
		SSLContext.setDefault(sslContext);
		
		SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();  
		SSLSocket sslsocket = (SSLSocket) sslSocketFactory.createSocket(
				"localhost", 9999);

		try {
			OutputStream outputstream = sslsocket.getOutputStream();
			OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
					outputstream);
			BufferedWriter bufferedwriter = new BufferedWriter(
					outputstreamwriter);

			bufferedwriter.write(msg);
			bufferedwriter.flush();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			sslsocket.close();
		}
	}

	public static void main(String[] args) throws Exception {
		try {
			URL url = Server.class.getClassLoader().getResource(
					"myTrustStore.jks");
			String jks = url.getFile();

			connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
					"This msg is from Java SSL Client :)");

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

SSLSocket Java Part1

1、使用环境变量,最基本的SSLSocket Server

package com.ats.ssl.socket;

import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

public class Server {

	static String delimiter = "=========================================================";

	public static void startListen(String keyStorePath, String keyStorePwd, int port) throws IOException {
		System.setProperty("javax.net.ssl.keyStore", keyStorePath);
		System.setProperty("javax.net.ssl.keyStorePassword", keyStorePwd);

		SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
		SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(port);

		while (true) {
			SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

			String protocols[] = { "TLSv1" };
			// String protocols[] = {"SSLv2Hello","TLSv1","SSLv3"};
			// String protocols[] = {"SSLv3"};
			sslsocket.setEnabledProtocols(protocols);

			DisplaySecurityLevel(sslsocket);
			DisplayCertificateInformation(sslsocket);

			try {
				InputStream inputstream = sslsocket.getInputStream();
				InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
				BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

				System.out.println(delimiter);
				String string = null;
				while ((string = bufferedreader.readLine()) != null) {
					System.out.println(string);
					System.out.flush();
				}
				System.out.println(delimiter);
			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				sslsocket.close();
			}
		}
	}

	static void DisplaySecurityLevel(SSLSocket sslsocket) {
		System.out.println(delimiter);
		SSLSession session = sslsocket.getSession();
		System.out.println("通讯协议: " + session.getProtocol());
		System.out.println("加密方式: "+session.getCipherSuite());
		System.out.println(delimiter);
	}

	static void DisplayCertificateInformation(SSLSocket sslsocket) {
		System.out.println(delimiter);
		Certificate[] localCertificates = sslsocket.getSession().getLocalCertificates();
		if (localCertificates == null || localCertificates.length == 0) {
			System.out.println("本地证书为空");
		} else {
			Certificate cert = localCertificates[0];
			System.out.println("本地证书类型: " + cert.getType());
			if (cert.getType().equals("X.509")) {
				X509Certificate x509 = (X509Certificate) cert;
				System.out.println("本地证书签发者: " + x509.getIssuerDN());
				System.out.println("本地证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
			}
		}

		try {
			Certificate[] peerCertificates = sslsocket.getSession().getPeerCertificates();

			if (peerCertificates == null || peerCertificates.length == 0) {
				System.out.println("远程证书为空");
			} else {
				Certificate cert = peerCertificates[0];
				System.out.println("远程证书类型: " + cert.getType());
				if (cert.getType().equals("X.509")) {
					X509Certificate x509 = (X509Certificate) cert;
					System.out.println("远程证书签发者: " + x509.getIssuerDN());
					System.out.println("远程证书有效期: " + x509.getNotBefore() + "至" + x509.getNotAfter());
				}
			}
		} catch (SSLPeerUnverifiedException e) {
			// e.printStackTrace();
			System.out.println("远程证书为空");
		}

		System.out.println(delimiter);
	}

	public static void main(String[] arstring) {
		try {
			URL url = Server.class.getClassLoader().getResource("myKeyStore.jks");
			String jks = url.getFile();
			startListen(jks, "sslTestPwd", 9999);

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

2、相应的,使用环境变量进行设置的,SSLSocket Client

package com.ats.ssl.socket;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.net.URL;

public class Client {
	public static void connectAndSend(String trustStorePath,
			String trustStorePwd, String ip, int port, String msg)
			throws IOException {
		System.setProperty("javax.net.ssl.trustStore", trustStorePath);
		System.setProperty("javax.net.ssl.trustStorePassword", trustStorePwd);

		SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
				.getDefault();
		SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
				"localhost", 9999);

		//String protocols[] = {"TLSv1"};
		String protocols[] = {"SSLv2Hello","TLSv1","SSLv3"};
		//String protocols[] = {"SSLv3"};
		sslsocket.setEnabledProtocols(protocols);

		try {
			OutputStream outputstream = sslsocket.getOutputStream();
			OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
					outputstream);
			BufferedWriter bufferedwriter = new BufferedWriter(
					outputstreamwriter);

			bufferedwriter.write(msg);
			bufferedwriter.flush();
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			sslsocket.close();
		}
	}

	public static void main(String[] arstring) {
		try {
			URL url = Server.class.getClassLoader().getResource(
					"myTrustStore.jks");
			String jks = url.getFile();

			connectAndSend(jks, "sslTestPwd", "127.0.0.1", 9999,
					"This msg is from Java SSL Client :)");

		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}
}

Java HTTP Premature EOF

这几天在调试HTTP通讯的时候,偶尔会发生下面的异常:
java.io.IOException: Premature EOF

主要原因是:
client在读取server返回的文件时,本来已经读完,但client又去读了一次
此时,就会抛出上面的异常

另外,公司搬家后,测试Java取回文件的效率,会出现两种诡异的延时:
1、打开输入流的时候,奇慢无比,要3~4s
2、在从输入流中读取时,不时会有200ms的奇怪延时
在不同的客户端机器上,从同一个服务端取回,会有不同的表现
貌似和客户端操作系统种类和JDK版本都有关,总之很诡异了。

唉~~,时间紧迫,只好找了其他方法解决

有人说是HTTP头设置问题,有人说是IPV6问题,试过后,问题依旧啊。

JS调用签名Applet访问本地文件导致权限不足

Applet访问本地文件,只需要用私有签名即可搞定。但用JS去调用相同的方法,却返回下面错误:

Exception in thread "Thread-14" java.security.AccessControlException: access denied ("java.io.FilePermission" "C:\TEMP" "read")
	at java.security.AccessControlContext.checkPermission(Unknown Source)
	at java.security.AccessController.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkRead(Unknown Source)
	at java.io.File.exists(Unknown Source)
        ......

主要是JS本身不被允许调用本地文件,从而JS调用的Applet方法也就没有权限去做访问本地文件这样的方法了。

为了解决这个问题:
首先,要用Manifest进行权限设置:

Manifest-Version: 1.0
Application-Name: AppletTest
Implementation-version: 1.0
Permissions: all-permissions
Caller-Allowable-Codebase: * localhost 127.0.0.1
Application-Library-Allowable-Codebase: *

然后,一般来说有两个方案来解决这个问题:

1、通过JS解决:
A、不要直接调用Applet的方法
B、而是用JS操作DOM,生成新的Applet的Tag
C、这样Applet可以在此从init进入,从而获得新的权限,儿不是JS的权限

2、通过AccessController.doPrivileged获取权限来解决:

    public String readFile() {
        final TestContent content = new TestContent();
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                content.text = readFileByLines("test.txt");
                return null;
            }
        });
        return content.text;
    }

Axis2 WebService Client

1、Axis2调用WebService一般有两种方法:
a、使用org.apache.axis2.rpc.client.RPCServiceClient自动生成PayLoad
b、使用org.apache.axis2.client.ServiceClient手动生成PayLoad

package com.ats.ws.client;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.log4j.Logger;

import com.ats.db.Person;
import com.ats.db.PersonAddResponse;

public class WSInvoker
{
	private static Logger logger = Logger.getLogger(WSInvoker.class);
	
	private static void invokeWebServiceRPC()
	{
		try
		{
			RPCServiceClient serviceClient = new RPCServiceClient();
			Options options = serviceClient.getOptions();
			options.setTo(new EndpointReference("http://localhost:8080/WebService1/services/PersonManager"));

			// 调用Action
			QName operation = new QName("http://ws.ats.com", "PersonAdd");

			// 调用参数类型和参数值
			Person p = new Person();
			Object req[] = new Object[] { p };
			p.setName("HI");
			Class[] reqClasses = new Class[] { PersonAddResponse.class };

			// 返回结果
			Object[] rsp = serviceClient.invokeBlocking(operation, req, reqClasses);
			PersonAddResponse r = (PersonAddResponse) rsp[0];
			logger.debug(r.getOperationReult());

		} catch (AxisFault e)
		{
			e.printStackTrace();
		}
	}

	public static void invokeWebServiceDocument()
	{
		try
		{
			ServiceClient serviceClient = new ServiceClient();
			Options opts = new Options();
			opts.setTo(new EndpointReference("http://localhost:8080/WebService1/services/PersonManager"));
			opts.setAction("urn:PersonAdd");
			serviceClient.setOptions(opts);

			// 发送请求并并得到返回结果
			OMElement res = serviceClient.sendReceive(createPayLoad());
			logger.debug(res.getFirstElement().getText());
		} catch (AxisFault e)
		{
			e.printStackTrace();
		}
	}

	public static OMElement createPayLoad()
	{
		OMFactory fac = OMAbstractFactory.getOMFactory();
		// 命名空间
		OMNamespace omNsXSD = fac.createOMNamespace("http://ws.ats.com", "xsd");
		OMNamespace omNsXS = fac.createOMNamespace("http://www.w3.org/2001/XMLSchema", "xs");
		// 指定方法
		OMElement method = fac.createOMElement("PersonAdd", omNsXSD);
		// 指定方法的参数
		OMElement p1 = fac.createOMElement("person", omNsXS);
		
		OMElement personName = fac.createOMElement("personName", omNsXS);
		personName.setText("personName");
		p1.addChild(personName);
		OMElement personid=fac.createOMElement("personid", omNsXS);
		personid.setText("");
		p1.addChild(personid);
		
		method.addChild(p1);
		return method;
	}

	public static void main(String[] args)
	{
		WSInvoker.invokeWebServiceRPC();
		WSInvoker.invokeWebServiceDocument();
	}
}

2、要想看到网络通讯的话,在log4j的配置文件中增加:

	<category name="org.apache.commons.httpclient">
		<priority value="WARN" />
	</category>
	<category name="httpclient.wire">
		<priority value="DEBUG" />
	</category>

Axis2 WebService Server

1、发布的几种方式
POJO+axis2-war:
这种方式比较适合简单功能,直接写一个POJO,放到axis2-war下的pojo目录即可
AAR+axis2-war:
这种方式比较适合发布,将服务打成aar包,放到axis2-war下的service目录即可
web+axis2:
这种方式比较适合调试,将axis2集成到web工程,个人比较喜欢这个方式

2、Service组成
a、服务类
PersonManager.java

package com.ats.ws;

import com.ats.db.Person;
import com.ats.db.PersonAddResponse;
import com.ats.db.PersonDAO;

public class PersonManager {
    public PersonAddResponse PersonAdd(Person person)
    {
        PersonAddResponse rsp = new PersonAddResponse();
        //PersonDAO dao = new PersonDAO();
        //rsp.setOperationReult(dao.InsertPerson(person));
        return rsp;
    }
}

b、服务描述文件
services/Person/META-INF/services.xml

<?xml version="1.0" encoding="UTF-8"?>

<service name="PersonManager">
	<description>PersonManagere</description>
	<parameter name="ServiceClass">com.ats.ws.PersonManager</parameter>
	<operation name="PersonAdd">
		<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
	</operation>
</service>

c、wsdl
可以自动生成,一般不需要指定

3、Axis2集成到WebApp的方式
a、axis2-web拷贝到project/WebContent下
b、conf、modules、services拷贝到project/WebContent/WEB-INF下
c、所需lib,拷贝到project/WebContent/WEB-INF/lib下
c、web.xml增加下面内容:

	<servlet>
		<servlet-name>AxisServlet</servlet-name>
		<servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet>
		<servlet-name>AxisAdminServlet</servlet-name>
		<servlet-class>org.apache.axis2.webapp.AxisAdminServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>AxisServlet</servlet-name>
		<url-pattern>/servlet/AxisServlet</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>AxisServlet</servlet-name>
		<url-pattern>*.jws</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>AxisServlet</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>AxisAdminServlet</servlet-name>
		<url-pattern>/axis2-admin/*</url-pattern>
	</servlet-mapping>

CGlib动态代理CallbackFilter

1、Car.java

package com.ast.cglib.test;

public class Car {

}

2、Truck.java

package com.ast.cglib.test;

public class Truck extends Car{

}

3、MyInterceptor.java

package com.ast.cglib.test;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyInterceptor implements MethodInterceptor{

	@Override
	public Object intercept(Object invoker, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		
		System.out.println("NewCarInterceptor intercept before invoke");
		
		Object result = proxy.invokeSuper(invoker, args);
		
		System.out.println("NewCarInterceptor intercept after invoke");
		
		return result;
	}

}

4、MyCallbackFilter.java

package com.ast.cglib.test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.CallbackFilter;

public class MyCallbackFilter implements CallbackFilter {
	
	public int accept(Method method) {
		if (method.getName().equals("NewTruck")) {
			return 0;
		} else {
			return 1;
		}
	}
}

5、CarFactory.java

package com.ast.cglib.test;

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;

public class CarFactory{
	public Car NewCar()
	{
		System.out.println("CarFactory NewCar");
		return new Car();
	}
	
	public Truck NewTruck()
	{
		System.out.println("CarFactory NewTruck");
		return new Truck();
	}
	
	public static void EnhancerTest()
	{
		Callback[] callbacks = new Callback[] {new MyInterceptor(),  NoOp.INSTANCE};
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(CarFactory.class);
		enhancer.setCallbacks(callbacks);
		enhancer.setCallbackFilter(new MyCallbackFilter());
		
		CarFactory fac = (CarFactory)enhancer.create();
		//NoOp
		fac.NewCar();
		//MyInterceptor
		fac.NewTruck();
	}
	
	public static void main(String[] args)
	{
		CarFactory.EnhancerTest();
	}
}

CGlib类型整合范例Mixin

1、IA1.java

package com.ast.cglib.test;

public interface IA1 {
	void methodA1();
}

2、IA2.java

package com.ast.cglib.test;

public interface IA2 {
	void methodA2();
}

3、A1Impl.java

package com.ast.cglib.test;

public class A1Impl implements IA1{

	@Override
	public void methodA1() {
		System.out.println("A1Impl methodA1");
	}

}

4、A2Impl.java

package com.ast.cglib.test;

public class A2Impl implements IA2{

	@Override
	public void methodA2() {
		System.out.println("A2Impl methodA2");
	}

}

5、MixinTest.java

package com.ast.cglib.test;

import net.sf.cglib.proxy.Mixin;

public class MixinTest {
	public static void main(String[] args) {

		Class[] interfaces = new Class[] { IA1.class, IA2.class };

		Object[] delegates = new Object[] { new A1Impl(), new A2Impl() };

		Object obj = Mixin.create(interfaces, delegates);

		IA1 a1 = (IA1) obj;
		a1.methodA1();

		IA2 a2 = (IA2) obj;
		a2.methodA2();
	}
}