xml-配置bean之lookup基于接口

siye@r480:~/svlution/workspace/springcore4322$ tree src/
src/
├── main
│   ├── java
│   │   ├── log4j.properties
│   │   └── ocn
│   │       └── site
│   │           └── springioc
│   │               └── domain
│   │                   ├── Person.java
│   │                   └── User.java
│   └── resources
└── test
    ├── java
    │   └── ocn
    │       └── site
    │           └── springioc
    │               └── domain
    │                   └── Runtest.java
    └── resources
        └── config
            └── application.xml

15 directories, 5 files
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.22.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.22.RELEASE</version>
    <scope>test</scope>
</dependency>
package ocn.site.springioc.domain;

public class Person {

}
package ocn.site.springioc.domain;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class User implements ApplicationContextAware {

	private ApplicationContext context;
	@SuppressWarnings("unused")
	private Person person;

	public Person getPerson() {
//		return person;
		return this.context.getBean(Person.class);
	}

	public void setPerson(Person person) {
		this.person = person;
	}

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

}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


	<!--
		方法的注入(lookup)

		概念理解
		lookup适用的需求场景:当bean A依赖于bean B时,不论是单例的还是多例的bean A,对于当前的bean A,
		容器只会给他一次初始化的机会;若要从容器中重新获取bean A的实例,那就不是当前的了,而是新的实例,
		此种情况仅适用bean A是多例模式下的.
		但是bean A需要在不同的时候,获取具有不同属性和状态的bean B,其实可使用setter方法替代?
		暂定.

		使用方式.
		第一种方式,是实现ApplicationContextAware接口.
		public class DependsInjectBeanA implements ApplicationContextAware {
		private ApplicationContext applicationContext;
		@Override
		public void setApplicationContext(ApplicationContext applicationContext)
		throws BeansException {
		this.applicationContext = applicationContext;
		}
		// 新增需要注入的方法,借用applicationContext实例.
		...
		}

		第二种方式,使用内嵌的look-up标签.
		a)此标签<look-up>需要内嵌到<bean>的标签下.使用模板如下:
		<look-up name="" bean=""/>
		其中属性name值指向的bean A中定义的获取新状态bean B的方法;
		属性bean值指向的是所依赖于的bean B的id或name的值,只要是存在容器中合法的bean即可.
		b)补充说明:
		在bean A的类中新增的方法,要遵循以下的格式:
		<public|protected> [abstract] <return-type> theMethodName(no-arguments);
		若是声明抽象的方法,bean A就必要时抽象类了,故此种方式一般不常使用;
		若是声明为具体方法,返回类型一般建议为bean B的类型,至于方法实体大多不要理会;
		其动态生成的子类会覆盖其新增的方法.一般可定义下面的格式:
		public returnTypeBeanB theMethodName(){
		return null;
		}
		这样定义了,动态生成的子类会覆盖重写这个方法的.

		第三种方式,就是替代内嵌标签<look-up>的方案了,使用注解@Lookup.
		该注解只设置了一个默认值value,此value值表示的指向依赖于bean B的id或name名称.
		若是没有设置就容器会自动根据方法的目标类型自动解析,但一般不建议这么做,因为会引起歧义.
		正确建议的使用方式应当是这样的:@Lookup("beanBofName").
		注意,此注解只能使用在方法上.
	-->

	<bean class="ocn.site.springioc.domain.Person" scope="prototype"></bean>
	<bean class="ocn.site.springioc.domain.User"></bean>

</beans>
package ocn.site.springioc.domain;

import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:config/application.xml")
public class Runtest {

	private final Logger logger = Logger.getLogger(this.getClass());
	private @Autowired ApplicationContext context;

	@Test
	public void run() throws Exception {
		User user = context.getBean(User.class);
		logger.info(user.getPerson());
		logger.info(user.getPerson());
	}

}
19-09-08 16:44:38 org.springframework.test.context.support.DefaultTestContextBootstrapper  =====>>> Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
19-09-08 16:44:38 org.springframework.test.context.support.DefaultTestContextBootstrapper  =====>>> Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@13fee20c, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@4e04a765, org.springframework.test.context.support.DirtiesContextTestExecutionListener@783e6358]
19-09-08 16:44:38 org.springframework.beans.factory.xml.XmlBeanDefinitionReader  =====>>> Loading XML bean definitions from class path resource [config/application.xml]
19-09-08 16:44:38 org.springframework.context.support.GenericApplicationContext  =====>>> Refreshing org.springframework.context.support.GenericApplicationContext@643b1d11: startup date [Sun Sep 08 16:44:38 CST 2019]; root of context hierarchy
19-09-08 16:44:38 ocn.site.springioc.domain.Runtest  =====>>> ocn.site.springioc.domain.Person@534df152
19-09-08 16:44:38 ocn.site.springioc.domain.Runtest  =====>>> ocn.site.springioc.domain.Person@52e677af
19-09-08 16:44:38 org.springframework.context.support.GenericApplicationContext  =====>>> Closing org.springframework.context.support.GenericApplicationContext@643b1d11: startup date [Sun Sep 08 16:44:38 CST 2019]; root of context hierarchy
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值