Spring4_05_Spring自动装配,方法注入,方法替换

Spring自动装配


前面我们的bean都是自己手动配置注入的,Spring提供有可以自动配置的机制:通过配置default-autowire属性,Spring IOC 容器可以自动为程序注入bean,默认是:no,不启动自动装配;default-autowire的类型有byName,byType,constructor

建议:自动装配机制要慎用,它屏蔽了装配细节,容易产生潜在的错误。

byName 


根据名字是否一样来自动装配注入。

还是之前用的那个例子:Person类属性:id,name,age,dog;  Dog类中属性:name.

现在在beans.xml添加属性:

default-autowire="byName"

xml里面有一个person的bean,两个dog的bean:

	<bean id="person1" class="com.java.entity.Person">
		<property name="id" value="1"></property>
		<property name="name" value="小李"></property>
		<property name="age" value="11"></property>
	</bean>
	<bean id="dog" class="com.java.entity.Dog">
		<property name="name" value="Jack"></property>
	</bean>
	<bean id="dog1" class="com.java.entity.Dog">
		<property name="name" value="Tom"></property>
	</bean>

可以看到person1里面的dog属性根本没有配置注入,但由于是byName自动注入,IOC容器会自动装配名字(id)为dog的bean,而不会注入名字不同(id为dog1)的bean.

测试:

	@Test
	public void test1() {
		Person person = (Person)ac.getBean("person1");
		System.out.println(person);
	}

id为dog的属性的值:Jack 被自动装配了进来。

byType


根据类型是否一致来自动装配注入,需要注意的是如果同一种类型的多个bean存在,就会报错。

在beans.xml替换为:

default-autowire="byType"

 如果按照上面的,xml里面有一个person的bean,两个dog的bean:就会报错:

去掉一个后在测试就不报错了:

 

 constructor


与byType相似,只不过他是根据构造方法注入而言的,根据类型,自动注入。

往bean.xml替换为:

default-autowire="constructor"

 在entity中写一个构造方法:

	public Person(Dog dog) {
		super();
		System.out.println("constructor...");
		this.dog = dog;
	}

如果使用了此构造方法,就会在控制台打印出"constructor..."

同时在xml中:

	<bean id="dog1" class="com.java.entity.Dog">
		<property name="name" value="Tom"></property>
	</bean>

测试;

 方法注入


Spring默认管理的bean都是以单实例存在的(作用域默认是单例 singleton),容器里只有一个实例。

可以通过配置prototype,实现多例。-----scope="prototype"

我们来看一下默认的情况:

通过两次获取bean,在控制台上打印是否相等来判断两次获取的实例是否为同一实例

System.out.println(ac.getBean("dog")==ac.getBean("dog"));

 

打印结果为true,说明两次获取的实例是同一实例。

配置prototype后:

	<bean id="dog" class="com.java.entity.Dog" scope="prototype">
		<property name="name" value="Tom"></property>
	</bean>

 

为false,说明两次获取的实例不是同一实例。每次都是取得一个新的bean。 

但是 ,如果把dog注入到person中,两次通过person来获取dog,两次获取的dog是否一样呢?

	<bean id="person1" class="com.java.entity.Person">
		<property name="id" value="1"></property>
		<property name="name" value="小李"></property>
		<property name="age" value="11"></property>
		<property name="dog" ref="dog"></property>
	</bean>
	<bean id="dog" class="com.java.entity.Dog" scope="prototype">
		<property name="name" value="Tom"></property>
	</bean>

测试:

	@Test
	public void test1() {
		Person person = (Person)ac.getBean("person1");
		Person person1 = (Person)ac.getBean("person1");
		//比较两次通过person获得的dog(配置了prototype属性)是否为同一实例
		System.out.println(person.getDog()==person1.getDog());
		//比较直接获取dog(配置了prototype属性)是否为同一实例
		System.out.println(ac.getBean("dog")==ac.getBean("dog"));
	}
}

结果:

出现这样的原因是:底层已经固定好注入的bean,默认是不能动态的改变的,但是Spring有机制是可以实现动态的注入的。

通过配置 <lookup-method>来实现。

首先要把要动态注入的方法抽象化(abstract) ,所以类也变成抽象类。具体实现由Spring来实现。

public abstract class Person {
public abstract Dog getDog() ;

 在注入时:

<bean id="person1" class="com.java.entity.Person">
		<property name="id" value="1"></property>
		<property name="name" value="小李"></property>
		<property name="age" value="11"></property>
		<lookup-method name="getDog" bean="dog"/>
</bean>

name为方法名

结果:

我们发现这样就能实现动态注入方法,每次通过方法获取的都是一个新实例。不过在日常开发中并不常见。

方法替换


通过实现MethodReplacer接口,重写里面的reimplement方法,来实现方法的替换。reimplement方法写要替换的方法的内容

具体通过下面实例:

我们定义两个person,把里面的getDog方法写死,就让它返回指定的名字。

person 里面的getDog():

	public Dog getDog() {
		Dog dog = new Dog();
		dog.setName("Jack");
		return dog;
	}

 person2:

import java.lang.reflect.Method;

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

public class Person2 implements MethodReplacer{
	
	@Override
	public Object reimplement(Object arg0, Method arg1, Object[] arg2) throws Throwable {
		Dog dog = new Dog();
		dog.setName("Tom");
		return dog;
	}	
}

 配置:

	<bean id="person1" class="com.java.entity.Person">
		<property name="id" value="1"></property>
		<property name="name" value="小李"></property>
		<property name="age" value="11"></property>
		<replaced-method name="getDog" replacer="person2"></replaced-method>
	</bean>
	<bean id="person2" class="com.java.entity.Person2"></bean>

这样就可以实现通过person1  的getDog方法替换成person2的方法内容。

测试:

	@Test
	public void test1() {
		Person person = (Person)ac.getBean("person1");
		System.out.println(person.getDog().getName());
	}

可以获得reimplement方法里的内容。开发中不常用,不过也要了解一下,万一用到也有个想法。 

附录


  1. 内容总结来源:Java1234学习路线 

猜你喜欢

转载自blog.csdn.net/qq_27163329/article/details/81147517
今日推荐