依赖注入

属性注入

构造方法注入

给Bean添加对应的构造方法

public class Book {
	private Integer id; 
	private String name; 
	private Double price;
	
	public Book() {
		System.out.println("-------book init----------");
	}
	
	public Book(Integer id, String name, Double price) { this.id = id;
		this.name = name;
		this.price = price;
	}
}

XML注入Bean


	
	
	

constructor-arg中的index和Book中的构造方法参数一一对应,写的顺序可以颠倒,但是index值和value要一一对应

另一种构造方法中的属性注入,则是通过直接指定参数名来注入:


	
	
	

如果有多个构造方法,则会根据给出参数个数以及参数类型,自动匹配到对应

的构造方法上,进而初始化一个对象。

set方法注入


	
	
	

set 方法注入,有一个很重要的问题,就是属性名。很多人会有一种错觉,觉得属性名就是你定义的属性名,这个是不对的。在所有的框架中,凡是涉及到反射注入值的,属性名统统都不是 Bean 中定义的属性名,而是通过 Java 中的内省机制分析出来的属性名,简单说,就是根据 get/set 方法分析出来的属性名。

p名字空间注入

p 名称空间注入,使用的比较少,它本质上也是调用了 set 方法。


外部Bean的注入

有时候,我们使用一些外部 Bean,这些 Bean 可能没有构造方法,而是通过 Builder
来构造的,这个时候,就无法使用上面的方式来给它注入值了。

例如在 OkHttp 的网络请求中,原生的写法如下:

public class OkHttpMain {
    public static void main(String[] args) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .build();
        Request request = new Request.Builder()
                .get()
                .url("http://b.hiphotos.baidu.com/image/h%3D300/sign=ad628627aacc7cd9e52d32d909032104/32fa828ba61ea8d3fcd2e9ce9e0a304e241f5803.jpg")
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                System.out.println(e.getMessage());
            }
@Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                FileOutputStream out = new FileOutputStream(new File("E:\\123.jpg"));
                int len;
                byte[] buf = new byte[1024];
                InputStream is = response.body().byteStream();
                while ((len = is.read(buf)) != -1) {
                    out.write(buf, 0, len);
                }
                out.close();
                is.close();
            }
        });
    }
}

这个 Bean 有一个特点,OkHttpClient 和 Request 两个实例都不是直接 new
出来的,在调用 Builder 方法的过程中,都会给它配置一些默认的参数。这种情况,我们可以使用 静态工厂注入或者实例工厂注入来给 OkHttpClient
提供一个实例。

1.静态工厂注入

首先提供一个 OkHttpClient 的静态工厂:

public class OkHttpUtils {
    private static OkHttpClient OkHttpClient;
    public static OkHttpClient getInstance() {
        if (OkHttpClient == null) {
            OkHttpClient = new OkHttpClient.Builder().build();
        }
        return OkHttpClient;
    }
}

在 xml 文件中,配置该静态工厂:


这个配置表示 OkHttpUtils 类中的 getInstance 是我们需要的实例,实例的名字就叫 okHttpClient。然后,在 Java 代码中,获取到这个实例,就可以直接使用了。

public class OkHttpMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        OkHttpClient okHttpClient = ctx.getBean("okHttpClient", OkHttpClient.class);
        Request request = new Request.Builder()
                .get()
                .url("http://b.hiphotos.baidu.com/image/h%3D300/sign=ad628627aacc7cd9e52d32d909032104/32fa828ba61ea8d3fcd2e9ce9e0a304e241f5803.jpg")
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                System.out.println(e.getMessage());
            }
@Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                FileOutputStream out = new FileOutputStream(new File("E:\\123.jpg"));
                int len;
                byte[] buf = new byte[1024];
                InputStream is = response.body().byteStream();
                while ((len = is.read(buf)) != -1) {
                    out.write(buf, 0, len);
                }
                out.close();
                is.close();
            }
        });
    }
}

2.实例工厂注入

实例工厂就是工厂方法是一个实例方法,这样,工厂类必须实例化之后才可以调用工厂方法。

这次的工厂类如下

public class OkHttpUtils {
    private OkHttpClient OkHttpClient;
    public OkHttpClient getInstance() {
        if (OkHttpClient == null) {
            OkHttpClient = new OkHttpClient.Builder().build();
        }
        return OkHttpClient;
    }
}

此时,在 xml 文件中,需要首先提供工厂方法的实例,然后才可以调用工厂方法:



自己写的 Bean 一般不会使用这两种方式注入,但是,如果需要引入外部 jar,外部 jar 的类的初始化,有可能需要使用这两种方式。

复杂属性注入

对象注入


    


    
    

可以通过 xml 注入对象,通过 ref 来引用一个对象。

数组注入

数组注入和集合注入在xml中的配置时一样的:


    
    
        
            足球
            篮球
            乒乓球
        
    


    
    

注意,array 节点,也可以被 list 节点代替。

当然,array 或者 list 节点中也可以是对象。


    
    
        
            足球
            篮球
            乒乓球
        
    
    
        
            
            
            
                
                
            
        
    


    
    


    
    

注意,即可以通过 ref 使用外部定义好的 Bean,也可以直接在 list 或者 array 节点中定义 bean。

Map注入


    
        
        
    

Properties注入


    
        99
        javaboy
    

你可能感兴趣的:(依赖注入)