Spring方法注入

在spring中注入方式有3中:

1, 构造函数注入

2, set方法注入

3, 接口注入(方法注入)


在spring中的bean默认范围都是单例, 但是在特定的情况下, 我们需要有如下的业务需要, 单例bean1需要依赖非单例bean2, 由于bean1始终是单例,所以如果不做出改变,每次获取的bean2也是同一个, 容器就没办法给我们提供一个新的bean2.


spring提供了如下方法:

1, 非ioc, 通过bean1实现ApplicationContextAware接口, 利用ApplicatioinContext在需要的时候getBean("bean1");

2, lookup方式

3, 其他


常用的1、2种方式

利用非IOC方式:

package org.xyz.svc.impl;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.xyz.svc.UserSvc;
import org.xyz.vo.User;

public class UserSvcImpl implements UserSvc, ApplicationContextAware{
	
	private ApplicationContext context;

	@Override
	public User initUser() {
		return (User)context.getBean("User");
	}

	@Override
	public void setApplicationContext(ApplicationContext context)
			throws BeansException {
		this.context = context;
	}

}
applicationContext.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!--
  - Middle tier application context definition for the image database.
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<bean name = "User" class = "org.xyz.vo.User" scope="prototype"></bean>

	<bean name="UserSvc" class = "org.xyz.svc.impl.UserSvcImpl">
	</bean>
	
</beans>
TestCase:

package test;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.xyz.svc.UserSvc;

public class TestUserSvc {
	
	private ApplicationContext applicationContext;
	
	@Before
	public void init() throws Exception{
		applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	}
	
	@Test
	public void testProcess(){
		UserSvc userSvc = (UserSvc)applicationContext.getBean("UserSvc", UserSvc.class);
		
		System.out.println(userSvc.initUser());
		System.out.println(userSvc.initUser());
		System.out.println(userSvc.initUser());
	}

}
运行结果:

org.xyz.vo.User@10f6d3
org.xyz.vo.User@1bcc0bc
org.xyz.vo.User@111a3a4

这种方式还是与spring framework产生了耦合,可以看到获取User的时候,指定了bean2的名称.


推荐使用下面的lookup方式实现, 因为这种方式使用了代理,spring利用cglib生成了需要的子类.

 去掉实现接口ApplicationContextAware, 定义抽象获取user的的方法为抽象方法

package org.xyz.svc.impl;

import org.xyz.svc.UserSvc;
import org.xyz.vo.User;

public abstract class UserSvcImpl implements UserSvc{
	
	public User initUser() {
		return createUser();
	}
	
	public abstract User createUser();

}
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
  - Middle tier application context definition for the image database.
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<bean name = "User" class = "org.xyz.vo.User" scope="prototype"></bean>

	<bean name="UserSvc" class = "org.xyz.svc.impl.UserSvcImpl">
		<lookup-method name="createUser" bean="User"/>
	</bean>
	
</beans>
TestCase

运行结果:

org.xyz.vo.User@6f50a8
org.xyz.vo.User@187814
org.xyz.vo.User@73a7ab
实现了我们想要的需求了.

注意:  被注入的方法定义要求: 

<public|protected> [abstract] <return-type> theMethodName(no-arguments);  

如果是抽象方法,会被spring动态生产的子类实现,如果不是抽象,会被覆盖. 所以类和方法修饰符不可以为final.






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值