IOC容器的一些功能

1. lookup方法的注入

springIOC容器具有复写Bean方法的能力,这项功能归功于CGLIB类包,CGLIB可以在运行期动态操作Class字节码,为Bean动态创建子类或实现类。

声明一个接口:MagicDog

public interface MagicDog {
     
    Dog getDog();
}

xml配置文件如下:

    <bean id="dog" class="com.ghq.cloud.source.Dog"
        p:name="aHuang" p:weight="23.4" p:age="1" scope="prototype"/>

    <bean id="magicDog" class="com.ghq.cloud.source.MagicDog">
        <lookup-method bean="dog" name="getDog"/>
    bean>

main方法如下:

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{
     "classpath:beans2.xml"});
MagicDog magicDog = (MagicDog) context.getBean("magicDog");
System.out.println(magicDog.getDog().hashCode());//1979313356
System.out.println(magicDog.getDog().hashCode());//1386883398
System.out.println(magicDog.getDog().hashCode());//1306854175
System.out.println(magicDog.getDog().hashCode());//1742920067

System.out.println(magicDog);
//com.ghq.cloud.source.MagicDog$$EnhancerBySpringCGLIB$$59867b60@6b0c2d26

可以发现magicDog 被CGLIB曾强处理了。
说明:lookup方法的注入的使用范围:一定是一个singleton的bean,获取prototype时使用的

2. 方法替换

Master类代码如下:

public class Master {
     
    private String name;
    private Dog dog = new Dog();
    private List<String> favorites = new ArrayList<>();
    //省略getter和setter
}

MyMethodRepalced类如下:

import org.springframework.beans.factory.support.MethodReplacer;

import java.lang.reflect.Method;
import java.util.Arrays;

public class MyMethodRepalced implements MethodReplacer {
     
    @Override
    public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
     

        System.out.println(obj.getClass());
        System.out.println(method);
        System.out.println(Arrays.asList(args));
        System.out.println("执行替换方法");
        return null;
    }
}

xml配置文件如下:

    <bean id="master" class="com.ghq.cloud.source.Master">
        <replaced-method name="getDog" replacer="myMethodRepalced"/>
    bean>

    <bean id="myMethodRepalced" class="com.ghq.cloud.source.MyMethodRepalced"/>

main方法代码:

public static void main(String[] args) {
     

    ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{
     "classpath:beans2.xml"});


    Object master = context.getBean("master");

    System.out.println(master);
    //com.ghq.cloud.source.Master$$EnhancerBySpringCGLIB$$a6e2687a@25359ed8

    Master m = (Master) master;
    System.out.println(m.getDog());
}

输出结果如下:

com.ghq.cloud.source.Master$$EnhancerBySpringCGLIB$$a6e2687a@25359ed8
class com.ghq.cloud.source.Master$$EnhancerBySpringCGLIB$$a6e2687a
public com.ghq.cloud.source.Dog com.ghq.cloud.source.Master.getDog()
[]
执行替换方法
null

你可能感兴趣的:(spring)