一分钟掌握FactoryBean的实现

 

一些代理和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) {

              //初始化log4jsystem 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 //调用类的名称

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FactoryBean是Spring框架中的一个接口,它提供了一种在容器中创建bean的方式。使用FactoryBean可以实现延迟加载,即在需要的时候才创建bean实例。下面是一个简单的示例: 1. 创建一个工厂类,实现FactoryBean接口: ``` public class MyBeanFactory implements FactoryBean<MyBean> { private boolean lazyInit = true; @Override public MyBean getObject() throws Exception { System.out.println("getObject() called"); return new MyBean(); } @Override public Class<?> getObjectType() { return MyBean.class; } @Override public boolean isSingleton() { return true; } public boolean isLazyInit() { return lazyInit; } public void setLazyInit(boolean lazyInit) { this.lazyInit = lazyInit; } } ``` 2. 配置bean: ``` <bean id="myBeanFactory" class="com.example.MyBeanFactory"> <property name="lazyInit" value="true"/> </bean> ``` 3. 在需要使用MyBean的地方,通过ApplicationContext获取实例: ``` ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); MyBean myBean = (MyBean) context.getBean("myBeanFactory"); ``` 在这个例子中,当ApplicationContext获取MyBean实例时,如果lazyInit属性为true,则不会立即创建MyBean实例,而是在第一次调用getObject()方法时才会创建。如果lazyInit属性为false,则在容器启动时就会创建MyBean实例。 使用FactoryBean可以实现延迟加载,避免在启动时就创建所有的bean,提高了应用程序的启动速度。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值