一些代理和FactoryBean有关知识的补充,对理解有关这类的题目有帮助的
1:每一个代理都有0个或多个方法,它有哪些方法要看它继承的是哪些接口,当应用程序来调用代理的某些方法时,代理把这些方法交给InvocationHandler的invoke()方法去处理,而返回调用实际方法结果的对象。(实际上这就是使用代理要达到的目的)
***Invoke()方法***
public Object invoke(Object proxy, Method method, Object[] args){
。 。 。 。 。 。
Object objValue = method.invoke(objTarget, args);
return objValue;
}
参数:proxy是代理的对象,Method是调用的那个方法,args是调用方法的参数。
例如:实际有方法xxx.Add(0,new String(“abc”)); 则:应用程序要调用代理对应的这个方法时,代理把这个方法交给它的invoke方法(Object objValue = method.invoke(objTarget, args);
)去处理,则:proxy就是xxx,Method是add,args是0和”abc”这两个对象。返回的对象(objValue)就是代理对象。
2:BeanFactory中的getBean(“id_name”)的调用过程
BeanFactory factory = new XmlBeanFactory(new ClassPathResourse(“applicationContext.xml”));
。 。 。 。 。 。
Object obj = factory.getBeab(“id_name”);
factory调用getBean()方法的时候,根据它提供的参数id_name到提供找到的xml文件中找到对应id相等的那个Bean,根据Bean的属性class找到对应哪个类,然后把xml文件中property中的属性值装载到Bean中,然后创建这个类的实例,然后判断这个类是否是实现了那个factoryBean接口的子类,如果不是就直接返回这个对象,如果是,就返回这个类中getObject()方法中返回的对象。
1:下面是一个完整的例子
1//自定义的接口
package cn.itcast;
public interface StudentService {
public void find(String name);
}
2://定义实现接口的类
package cn.itcast;
public class StudentServices implements StudentService {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void find(String name){//实现接口的方法
System.out.println(name);
}
public String toString(){
return name;
}
}
3://定义代理类,在调用实际的类的方法之前做拦截,打出一些日志信息
package cn.itcast;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.apache.commons.logging.LogFactory;
public class MyHandler implements InvocationHandler {
private StudentServices obj = null;
public MyHandler(StudentServices obj) {
this.obj = obj;
}
//实现代理类的invoke方法。
public Object invoke(Object arg0, Method method, Object[] args) throws Throwable {
LogFactory.getLog(this.getClass()).info(
method.getName() + " 方法被调用!");
Object object = method.invoke(obj,args);
return object;
}
}
4://工厂类实现FactoryBean接口,调用代理类
package cn.itcast;
import java.lang.reflect.Proxy;
import org.springframework.beans.factory.FactoryBean;
public class MyFactoryBean implements FactoryBean{
//target 表示定义的实际类,myInterface表示定义的接口
private String target = null;
private String myInterface = null;
public String getMyInterface() {
return myInterface;
}
public void setMyInterface(String myInterface) {
this.myInterface = myInterface;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
//注意:下面getObject方法:如果根据getBean()方法找到的xml文件中Bean对应的类的实例不是MyFactoryBean
//的子类,则直接返回MyFactoryBean的对象,否则返回getObject()中返回的对象。
public Object getObject() throws Exception {
Class [] clazzes = new Class[]{Class.forName(myInterface)};
Class clazz = Class.forName(target);
StudentServices objTarget = (StudentServices)clazz.newInstance();
//产生代理类的实例
Object objProxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),clazzes,new MyHandler(objTarget));
return objProxy;
}
public Class getObjectType() {
return null;
}
public boolean isSingleton() {
return false;
}
}
5://调用类
package cn.itcast;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.BasicConfigurator;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.*;
public class MainClass {
public static void main(String[] args) {
//初始化log4j的system 的properties
BasicConfigurator.configure();
Log log = LogFactory.getLog(MainClass.class);
//引用XmlBeanFactory找到xml的配置文件,这里用的是相对路径。
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("cn/itcast/applicationContext.xml"));
//调用getBean方法,参数是xml文件中Bean对应的id
StudentService obj = (StudentService)factory.getBean("myfactorybean");
obj.find("maxianzhong");
log.info(obj.getClass().getName());
}
}
5:配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="myfactorybean" class="cn.itcast.MyFactoryBean">
<property name="target">
<value>cn.itcast.StudentServices</value>
</property>
<property name="myInterface">
<value>cn.itcast.StudentService</value>
</property>
</bean>
</beans>
下面是我运行上面这个FactoryBean的结果:
500 [main] INFO cn.itcast.MyHandler - find 方法被调用!//日志信息
maxianzhong//调用find方法后输出的信息
500 [main] INFO cn.itcast.MainClass - $Proxy0 //调用类的名称