一些代理和FactoryBean有关知识的补充

来源:互联网 发布:linux get请求url 编辑:程序博客网 时间:2024/05/22 08:17
 

一些代理和FactoryBean有关知识的补充,对理解有关这类的题目有帮助的

1:每一个代理都有0个或多个方法,它有哪些方法要看它继承的是哪些接口,当应用程序来调用代理的某些方法时,代理把这些方法交给InvocationHandlerinvoke()方法去处理,而返回调用实际方法结果的对象。(实际上这就是使用代理要达到的目的)

***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就是xxxMethodaddargs0”abc”这两个对象。返回的对象(objValue)就是代理对象。

 

 

 

2BeanFactory中的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) {

              //初始化log4jsystemproperties

              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 //调用类的名称

原创粉丝点击