67,549
社区成员




PUB pub = new PUB
pub.X1.Y(); //调用的时候 把a、b、c包这层隐藏掉,X1是类名,Y()就是X1的方法
//或者
pub.xxx("X1").Y(); //其中X1就是a、b、c包下的一个类,Y()就是X1的方法
接口:
package ISyaHi;
public interface ISayHi {
public String SayHi(String name);
}
实现类:
package SayHiImp;
import ISyaHi.ISayHi;
public class SayHiEnImp implements ISayHi {
public SayHiEnImp()
{
}
public String SayHi(String name) {
return "Hello! "+name.toUpperCase()+" This JAVA Word!";
}
package SayHiImp;
import ISyaHi.ISayHi;
public class SayHiZhImp implements ISayHi {
public SayHiZhImp()
{
}
public String SayHi(String name) {
return "你好! "+name.toUpperCase()+" 这是JAVA世界!";
}
}
控制类:
package SayHiController;
import ISyaHi.ISayHi;
import XMLPrass.XmlPrass;
public class Controller {
private ISayHi iSatHi;
private XmlPrass xmlPrass;
public Controller ()
{
try{
xmlPrass=XmlPrass.newInstance();
if(xmlPrass.sax().equals("ZH")){
iSatHi=(ISayHi)Class.forName("SayHiImp.SayHiZhImp").newInstance();
}else{
iSatHi=(ISayHi)Class.forName("SayHiImp.SayHiEnImp").newInstance();
}
}catch(Exception e){
System.out.println(e);
}
}
public ISayHi getSayHi()
{
return iSatHi;
}
}
XML解析类:
package XMLPrass;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XmlPrass {
private static XmlPrass xmlPrass=null;
private XmlPrass(){}
public String sax() {
String result="";
try{
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=builderFactory.newDocumentBuilder();
Document document=builder.parse(new File("src/MyXml.xml"));
Element element=document.getDocumentElement();
NodeList nl=element.getElementsByTagName("say-configuation");
result=nl.item(0).getAttributes().getNamedItem("src").getTextContent();
}catch(Exception e){
System.out.println(e);
}
return result;
}
public static XmlPrass newInstance(){
if(xmlPrass==null){
xmlPrass=new XmlPrass();
}
return xmlPrass;
}
}
测试类:
package SayHiMain;
import SayHiController.Controller;
public class SayHi {
/**
* @param args
*/
public static void main(String[] args) {
Controller controller=new Controller();
System.out.println(controller.getSayHi().SayHi("jack"));
}
}
MyXml.xml
<?xml version="1.0" encoding="UTF-8"?>
<say>
<say-configuation src="EN"/>
<say-class name="ZH" class="SayHiImp.SayHiZhImp" />
<say-class name="EN" class="SayHiImp.SayHiEnImp" />
</say>
package entity;
public class Pub {
private String pkg = "a";
public Pub(){
}
public void setPackage(String pkg){
this.pkg = pkg;
}
public Object loadClass(String className){
try {
String selfPath = Pub.class.getPackage().getName();
Class<?> clazz = Class.forName(selfPath+"."+this.pkg+"."+className);
return clazz.newInstance();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
//访问A包下的新增的IX4实现,注意:这里一定要转接口,不能转为a.X4,因为a.X4对于PUB不可见
((IX4)a.getProxy("X4")).printX4();
之前代码有点问题,类加载器会多次加载同一个类,这里也简单的修改了一下PackageClassLoader
public class PackageClassLoader extends ClassLoader {
private String packageName;
private Map<String, Class> cache = new HashMap<>();
public PackageClassLoader(String packageName) {
super();
this.packageName = packageName;
}
public PackageClassLoader(String packageName, ClassLoader parentLoader) {
super(parentLoader);
this.packageName = packageName;
}
protected java.lang.Class<?> findClass(String name)
throws ClassNotFoundException {
String fullClassName = packageName + "." + name;
byte[] classData = getClassData(fullClassName);
if (classData == null) {
throw new ClassNotFoundException("class [" + fullClassName
+ "] not found ");
} else {
if (cache.containsKey(fullClassName)) {
return cache.get(fullClassName);
} else {
Class clazz = defineClass(fullClassName, classData, 0,
classData.length);
cache.put(fullClassName, clazz);
return clazz;
}
}
};
private byte[] getClassData(String name) {
try {
InputStream is = new FileInputStream(rootClassName(name));
ByteArrayOutputStream os = new ByteArrayOutputStream();
int buffSize = 4096;
byte[] buff = new byte[buffSize];
int readNum = -1;
while ((readNum = is.read(buff)) != -1) {
os.write(buff, 0, readNum);
}
return os.toByteArray();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private String rootClassName(String name) {
return this.getParent().getResource("").getFile() + File.separator
+ name.replace(".", File.separator) + ".class";
}
}
public class DynProxy implements InvocationHandler {
private String className;
private String packageName;
private ClassLoader loader;
public DynProxy(String packageName) {
super();
this.packageName = packageName;
this.loader = new PackageClassLoader(this.packageName);
}
@SuppressWarnings("rawtypes")
public Object getProxy(String className){
this.className = className;
try {
return Proxy.newProxyInstance(this.loader,
((Class) this.loader.loadClass(className)).getInterfaces(), this);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(getInstance(className), args);
}
// 使用类加载器去寻找对应包下的类,再创建实例
@SuppressWarnings({"rawtypes" })
private Object getInstance(String className) {
try {
return ((Class) this.loader.loadClass(className)).newInstance();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public static void main(String[] args) {
DynProxy a = new DynProxy("com.bear.a");
DynProxy b = new DynProxy("com.bear.b");
DynProxy c = new DynProxy("com.bear.c");
((IX1)a.getProxy("X1")).printX1();
((IX1)b.getProxy("X1")).printX1();
((IX1)c.getProxy("X1")).printX1();
((IX2)a.getProxy("X2")).printX2();
((IX3)a.getProxy("X3")).printX3();
}
public class PUB
{
public static void main( String[] args )
{
/**IProxy是暴露给外部的接口集合,这里是暴露了IX1,IX2,IX3接口
*a、b、c三个包中的类是使用单独的加载器加载的,而PUB和IProxyImpl是由系统类加载器加载,
*所以三个包中的实现对于PUB和IProxyImpl都是不可见的,他们只能看到接口看不到实现。
*不信的话你可以修改后面IProxyImpl代码,试试将object强转为接口(IX1) 改为强转成实现(X1),看看有什么结果
*/
IProxy A = new IProxyImpl("com.bear.a");
IProxy B = new IProxyImpl("com.bear.b");
IProxy C = new IProxyImpl("com.bear.c");
A.printX1();
B.printX2();
C.printX3();
}
}
/**
* IProxyImpl内部有一个类加载器,负责加载对应包下的类。
*
* 实现了IProxy接口集合IX1,IX2,IX3,这个类实际上是一个负责加载实现并调用的代理类
* @author Bear
*
*/
public class IProxyImpl implements IProxy
{
private String packageName;
private ClassLoader loader;
public IProxyImpl(String packageName)
{
super();
this.packageName = packageName;
loader = new PackageClassLoader(this.packageName);
}
@Override
public void printX1()
{
((IX1) this.getInstance("X1")).printX1();
}
@Override
public void printX2()
{
((IX2) this.getInstance("X2")).printX2();
}
@Override
public void printX3()
{
((IX3) this.getInstance("X3")).printX3();
}
//使用类加载器去寻找对应包下的类,再创建实例
private Object getInstance( String className )
{
try
{
return ((Class) loader.loadClass(className)).newInstance();
}
catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InstantiationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public class PackageClassLoader extends ClassLoader
{
private String packageName;
public PackageClassLoader(String packageName)
{
super();
this.packageName = packageName;
}
public PackageClassLoader(String packageName, ClassLoader parentLoader)
{
super(parentLoader);
this.packageName = packageName;
}
protected java.lang.Class<?> findClass( String name )
throws ClassNotFoundException
{
String fullClassName = packageName + "." + name;
byte[] classData = getClassData(fullClassName);
if (classData == null)
{
throw new ClassNotFoundException("class [" + fullClassName
+ "] not found " );
}
else
{
return defineClass(fullClassName, classData, 0, classData.length);
}
};
private byte[] getClassData( String name )
{
try
{
InputStream is = new FileInputStream(rootClassName(name) );
ByteArrayOutputStream os = new ByteArrayOutputStream();
int buffSize = 4096;
byte[] buff = new byte[buffSize];
int readNum = -1;
while ((readNum = is.read(buff)) != -1)
{
os.write(buff, 0, readNum);
}
return os.toByteArray();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private String rootClassName(String name)
{
return this.getParent().getResource("").getFile()+File.separator+name.replace(".",File.separator)+".class";
}
}
public interface IProxy extends IX1,IX2,IX3
{
}