JDK动态代理范例

1、ProxyFactory.java

package com.ats.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class ProxyFactory implements InvocationHandler{
	private Object invoker;
	private List<Object> interceptors;
	
	private ProxyFactory(Object invoker,List<Object> interceptors)
	{
		this.invoker = invoker;
		if(interceptors==null)
		{
			this.interceptors = new ArrayList<Object>();
		}
		else
		{
			this.interceptors = interceptors;
		}
	}
	
    public static final Object newInstance(Object invoker,List<Object> interceptors)
    {
        return java.lang.reflect.Proxy.newProxyInstance(invoker.getClass().getClassLoader(),
        		invoker.getClass().getInterfaces(), new ProxyFactory(invoker,interceptors));
    }
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		
		for(Object o : interceptors)
		{
			if(o instanceof IProxyBefore)
			{
				((IProxyBefore)o).BeforeInvoke();
			}
		}
		
		try
		{
			result = method.invoke(invoker, args);
		}
		catch(Exception ex)
		{
			for(Object o : interceptors)
			{
				if(o instanceof IProxyThrow)
				{
					((IProxyThrow)o).ThrowInvoke();
				}
			}
		}
		
		for(Object o : interceptors)
		{
			if(o instanceof IProxyAfter)
			{
				((IProxyAfter)o).AfterInvoke();
			}
		}
		return result;
	}
}

2、IProxyBefore.java

package com.ats.proxy;

public interface IProxyBefore {
	public void BeforeInvoke();
}

3、IProxyAfter.java

package com.ats.proxy;

public interface IProxyAfter {
	public void AfterInvoke();
}

4、IProxyAround.java

package com.ats.proxy;

public interface IProxyAround extends IProxyBefore,IProxyAfter{
}

5、IProxyThrow.java

package com.ats.proxy;

public interface IProxyThrow {
	public void ThrowInvoke();
}

6、ICarFactory.java

package com.ats.test;

public interface ICarFactory {
	public Car NewCar();
}

7、Car.java

package com.ats.test;

public class Car {
	public Car()
	{
		System.out.println("This is a new Car");
	}
}

8、IProxyBefore.java

package com.ats.test;

import com.ats.proxy.IProxyBefore;

public class CarFactoryBefore implements IProxyBefore{

	@Override
	public void BeforeInvoke() {
		System.out.println("CarFactoryBefore BeforeInvoke");
	}

}

9、CarFactoryAfter.java

package com.ats.test;

import com.ats.proxy.IProxyAfter;

public class CarFactoryAfter implements IProxyAfter {

	@Override
	public void AfterInvoke() {
		System.out.println("CarFactoryAfter AfterInvoke");
	}

}

10、CarFactoryAround .java

package com.ats.test;

import com.ats.proxy.IProxyAround;

public class CarFactoryAround implements IProxyAround{
	@Override
	public void AfterInvoke() {
		System.out.println("CarFactoryAround AfterInvoke");
	}
	
	@Override
	public void BeforeInvoke() {
		System.out.println("CarFactoryAround BeforeInvoke");
	}
}

11、CarFactoryThrow.java

package com.ats.test;

import com.ats.proxy.IProxyThrow;

public class CarFactoryThrow implements IProxyThrow {
	@Override
	public void ThrowInvoke() {
		System.out.println("CarFactory ThrowInvoke");
	}
}

12、CarFactory.java

package com.ats.test;

import java.util.ArrayList;
import java.util.List;

import com.ats.proxy.IProxyAround;
import com.ats.proxy.IProxyThrow;
import com.ats.proxy.ProxyFactory;

public class CarFactory implements ICarFactory {
	public Car NewCar()
	{
		return new Car();
	}
	
	public static void main(String[] args)
	{
		CarFactory fac = new CarFactory();
		CarFactoryAfter after = new CarFactoryAfter();
		CarFactoryBefore before = new CarFactoryBefore();
		CarFactoryAround around = new CarFactoryAround();
		CarFactoryThrow _throw = new CarFactoryThrow();
		List<Object> l = new ArrayList<Object>();
		l.add(after);
		l.add(before);
		l.add(around);
		l.add(_throw);
		
		ICarFactory factory = (ICarFactory)ProxyFactory.newInstance(fac,l);
		factory.NewCar();
	}
}

JKS密码验证

下面的程序用来验证JKS的文件及密码是否正确

public static URL getStoreURL(String storePath) throws IOException
{
	URL url = null;
	// First see if this is a URL
	try
	{
		url = new URL(storePath);
	}
	catch (MalformedURLException e)
	{
		// Not a URL or a protocol without a handler so...
		// next try to locate this as file path
		File tst = new File(storePath);
		if (tst.exists() == true)
		{
			url = tst.toURL();
		} else
		{
			// not a file either, lastly try to locate this as a classpath
			// resource
			if (url == null)
			{
				ClassLoader loader = Thread.currentThread().getContextClassLoader();
				url = loader.getResource(storePath);
			}
		}
	}
	// Fail if no valid key store was located
	if (url == null)
	{
		String msg = "Failed to find url=" + storePath + " as a URL, file or resource";
		throw new MalformedURLException(msg);
	}
	return url;
}

public static KeyStore loadKeyStore(String storeType, URL storePathURL, String storePassword) throws Exception
{
	KeyStore keyStore = null;
	String provider = null;
	String providerName = null;

	if (provider != null)
	{
		keyStore = KeyStore.getInstance(storeType, provider);
	} else
		if (providerName != null)
		{
			keyStore = KeyStore.getInstance(storeType, providerName);
		} else
		{
			keyStore = KeyStore.getInstance(storeType);
		}
	if (storePathURL == null) { throw new Exception("Can not find store file for url because store url is null."); }
	// now that keystore instance created, need to load data from file
	InputStream keyStoreInputStream = null;
	try
	{
		keyStoreInputStream = storePathURL.openStream();
		// is ok for password to be null, as will just be used to check
		// integrity of store
		char[] password = storePassword != null ? storePassword.toCharArray() : null;
		keyStore.load(keyStoreInputStream, password);
	}
	finally
	{
		if (keyStoreInputStream != null)
		{
			try
			{
				keyStoreInputStream.close();
			}
			catch (IOException e)
			{
				// no op
			}
			keyStoreInputStream = null;
		}
	}
	return keyStore;
}

public static String verifyP12(String p12Path,String p12Pwd)
{
            String ret = "验证成功";
            try
            {
	URL ksURL = getStoreURL(p12Path);
                if(ksURL==null)throw new Exception(p12Path+"文件未找到");
                    
	loadKeyStore("PKCS12",ksURL,p12Pwd);
            }
            catch(Exception ex)
            {
                ret = ex.getMessage();
                ex.printStackTrace();
            }
            return ret;
}

public static String verifyJks(String jksPath,String jksPwd)
{
            String ret = "验证成功";
            try
            {
	URL ksURL = getStoreURL(jksPath);
	loadKeyStore("JKS",ksURL,jksPwd);
                
                if(ksURL==null)throw new Exception(jksPath+"文件未找到");
            }
            catch(Exception ex)
            {
                ret = ex.getMessage();
                ex.printStackTrace();
            }
            
            return ret;
}

keytool生成key

生成keystore及cert

#生成私钥
keytool -genkey -validity 10000 -keyalg RSA -dname "CN=neohope OU=neohope O=neohope L=Shanghai C=CN" -keystore node1.jks -alias node1 -keypass password -storepass password 
#导出证书
keytool -export -file node1.crt -keystore node1.jks -alias node1 -keypass password -storepass password 
#生成truststore
keytool -import -trustcacerts -file node1.crt -keystore trust.jks -alias node1 -keypass password -storepass password 
#查看
keytool -list -keystore node1.jks
keytool -list -keystore trust.jks

jks转p12

keytool -importkeystore -srckeystore node1.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore node1.p12 -srcstorepass password -deststorepass password

Tomcat配置TLS

%TOMCAT_HOME%/conf/server.xml中添加以下配置即可

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
	       clientAuth="false" sslProtocol="TLS"
               keystoreFile="TOMCAT_HOME\conf\AXDS_2012_Keystore.jks"
               keystorePass="password"
	       truststoreFile="TOMCAT_HOME\conf\AXDS_2012_Truststore.jks" 
	       truststorePass="password"            
	       />

SpringAOP的两种代理方式

SpringAOP有两种代理方式:JDK动态代理和CGLIB。
如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理(该目标类型实现的所有接口都将被代理)。
如果被代理的目标对象没有实现任何接口,则会使用CGLIB代理。

所以,当你将一个JDK动态代理的对象Cast为一个Class而不是Interface的时候,就会报ClassCastException

这时,就要强制使用CGLIB代理

<aop:config proxy-target-class="true">
...
</aop:config>

或在使用@AspectJ时强制使用CGLIB代理

<aop:aspectj-autoproxy proxy-target-class="true">
    <aop:include name="bean1" />
    <aop:include name="bean2" />
    ....
</aop:aspectj-autoproxy>

Java多线程同步的几种方式

1、原子变量
AtomicBoolean
AtomicInteger
AtomicLong
AtomicReference
AtomicStampedReference
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray

2、Unsafe类
Unsafe.monitorEnter(this);
Unsafe.monitorExit(this);

3、synchronized关键字
同步静态方法
同步普通方法
同步代码块

4、锁
Object.wait()方法和Object.notify()方法:

5、ReentrantLock重入锁
Condition

6、ReadWriteLock读写锁
StampedLock

7、Semaphore信号量

8、BlockingQueue阻塞队列
ArrayBlockingQueue
LinkedBlockingQueue
PriorityBlockingQueue
LinkedBlockingDeque
SynchronousQueue
DelayQueue

9、CyclicBarrier

10、CountDownLatch

11、Phaser

12、Exchanger

13、ForkJoinPool
RecursiveTask

13、Future
CompletionService
CompletableFuture
FutureTask

14、Collections
Collections.synchronizedList
Collections.synchronizedSet
Collections.synchronizedMap

15、volatile变量
可以解决并发读的问题,无法单独解决并发写的问题

Java多线程实现的几种方式

1、继承Thread类

2、实现Runnable接口

3、实现Callable接口+Future封装

4、定时器

5、使用Executors提供的ExecutorService
Executors.newCachedThreadPool
Executors.newFixedThreadPool
Executors.newScheduledThreadPool
Executors.newSingleThreadExecutor
Executors.newWorkStealingPool

6、自定义ThreadPoolExecutor+ThreadFactory

7、parallelStream

8、Fork Join
ForkJoinPool
RecursiveTask
RecursiveAction

9、调用本地方法
使用JNI等

双击运行的jar包

让jar包可以双击运行,其实很简单

1.写一个manifest.mf文件,里面只有两行
第一行为Main-Class
第二行为空行
注意冒号后面有一个空格

Main-Class: YourClassName

2.用jar命令打包

jar -cvfm xxx.jar xxx.mf classfiles

3.然后就可以运行了

要注意,双击运行jar包时,
系统会调用javaw而不是java,
因此命令行输出是看不到的。

JNI简单例子1

1.Java代码CallApi.java

class CallApi{
    private native String showMessageBox(String msg);
    private native double getRandomDouble();

    static{
        try{
            System.loadLibrary("CallApi");
            System.out.println("Loaded CallApi");
        }catch(UnsatisfiedLinkError e){
            //nothing to do
            System.out.println("Couldn't load CallApi");
            System.out.println(e.getMessage());
        }
    }

    public static void main(String args[]){
        CallApi api = new CallApi();
        double randomNumber = api.getRandomDouble();
        String retval = api.showMessageBox("Hello from Java!\n"+
            "The native random number: "+randomNumber);
            System.out.println("The native string: "+retval);
    }
}

2.生成dll的CallApi.h文件

javah -classpath . -jni CallApi
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class CallApi */

#ifndef _Included_CallApi
#define _Included_CallApi
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     CallApi
 * Method:    showMessageBox
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_CallApi_showMessageBox
  (JNIEnv *, jobject, jstring);

/*
 * Class:     CallApi
 * Method:    getRandomDouble
 * Signature: ()D
 */
JNIEXPORT jdouble JNICALL Java_CallApi_getRandomDouble
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

3.手写dll的CallApi.c文件

#include"CallApi.h"
#include <windows.h>
#include <time.h>

//#pragma comment(lib,"user32.lib")

JNIEXPORT jstring JNICALL Java_CallApi_showMessageBox
  (JNIEnv *env, jobject thisObject, jstring js)
{
    //first convert jstring to const char for use in MessageBox
    const jbyte* argvv = (*env)->GetStringUTFChars(env, js, NULL);
    char* argv =(char *) argvv;

    //Call MessageBoxA
    MessageBox(NULL, argv, "Called from Java!", MB_ICONEXCLAMATION | MB_OK);
    return js;

}


JNIEXPORT jdouble JNICALL Java_CallApi_getRandomDouble
  (JNIEnv *env, jobject thisObject)
{
    double num1;
    srand((unsigned)(time(0)));
    num1 = ((double)rand()/(double)RAND_MAX);

    return num1;
}

4.编译
注意1:要引用jdk下的include目录下文件,因此要增加引用文件路径
注意2:用MT而不是MD

5.运行

java -Djava.library.path=. CallApi