spring之lookup-method注入

lookup method注入是spring动态改变bean里方法的实现。方法执行返回的对象,使用spring内原有的这类对象替换,通过改变方法返回值来动态改变方法。内部实现为使用cglib方法,重新生成子类,重写配置的方法和返回对象,达到动态改变的效果。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--lookup-method动态注入-->
    <bean id="myCommand" class="com.picc.spring.lookupmethod.SynCommand" scope="prototype"></bean>
    <bean id="commandManager" class="com.picc.spring.lookupmethod.CommandManager">
        <lookup-method name="crateCommand" bean="myCommand"></lookup-method>
    </bean>
</beans>
package com.picc.spring.lookupmethod;

public class Command{
    private Object commcandState;

    public Command() {
        System.out.println("i am command");
    }
    public void setCommcandState(Object commcandState) {
        this.commcandState = commcandState;
    }
    public Object execute() {
        return "hello look-up method";
    }
}

package com.picc.spring.lookupmethod;

public class AsyncCommand extends Command{

    public AsyncCommand() {
        System.out.println("i am async");
    }
    public Object execute() {
        return "hello look-up method  AsyncCommand";
    }
}

package com.picc.spring.lookupmethod;

public class SynCommand extends Command{
    public SynCommand() {
        System.out.println("i am sync");
    }

    public Object execute() {
        return "hello look-up method  SynCommand";
    }
}

package com.picc.spring.lookupmethod;

public abstract class CommandManager {
    public Object process(Object commandState) {
        Command command = crateCommand();
        System.out.println(command);
        command.setCommcandState(commandState);
        return command.execute();
    }

    protected abstract Command crateCommand();
}

  @Test
  public void testlookupMethod(){
    CommandManager clientService = classPath.getBean("commandManager", CommandManager.class);
    clientService.process(1);
//    clientService = classPath.getBean("commandManager", CommandManager.class);
    clientService.process(1);
    System.out.println(clientService);
  }

在这里插入图片描述
其中,最为核心的部分就是lookup-method的配置。上面代码中,我们可以看到crateCommand()方法是个抽象方法,我们并没有实现它啊,那它是怎么调用的呢。这里的奥妙就是Srping应用了CGLIB(动态代理)类库。Spring在初始化容器的时候对配置的bean做了特殊处理,Spring会对bean指定的class做动态代理,代理标签中name属性所指定的方法,返回bean属性指定的bean实例对象。每次我们调用CommandManager 这个bean的crateCommand()方法时,其实是调用了CGLIB生成的动态代理类的方法。

    <bean id="commandManager" class="com.picc.spring.lookupmethod.CommandManager">
        <lookup-method name="crateCommand" bean="myCommand"></lookup-method>
    </bean>

method是commandManager中的一个方法,commandManager和crateCommand是不是抽象都无所谓,不会影响CGLIB的动态代理,根据项目实际需求去定义。non-singleton-bean指的是lookup-method中bean属性指向的必须是一个非单例模式的bean,当然如果不是也不会报错,只是每次得到的都是相同引用的bean(同一个实例),这样用lookup-method就没有意义了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值