Spring 框架中注入或替换方法实现

无状态 Bean 的作用域是 singleton 单实例,如果我们向 singleton 的 Bean A 注入 prototype 的 Bean B,并希望每次调用 Bean A 的 getBeanB() 时都能返回一个新的 Bean B ,这样的要求使用传统的注入方式是无法实现的 。 因为 singleton 的 Bean 注入关联 Bean 的动作只发生一次,虽然 Bean B 的作用域是 prototype 类型,但通过 getBeanB() 返回的对象还是最开始注入的那个 bean B。

所以如果希望每次调用 BeanA 的 getBeanB() 时都能返回一个新的 BeanB 的一种可选的方案是:让 Bean A 实现 BeanFactoryAware 接口,从而能够访问容器,然后以下面这种方式来实现。

首先配置 XML:

<bean id="author" class="net.deniro.spring4.bean.Author" scope="prototype"/>
<bean id="book" class="net.deniro.spring4.bean.Book"
   p:name="面纱">
</bean>

bean author 的 scope 设置为 prototype。

Book 类实现 BeanFactoryAware 接口:

public class Book implements BeanFactoryAware {
 ...
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  this.factory = beanFactory;
}
public Author getPrototypeAuthor() {
  return (Author) factory.getBean("author");
  }
}

单元测试:

ApplicationContext context;
@BeforeMethod
public void setUp() throws Exception {
  context = new ClassPathXmlApplicationContext("beans5-5.xml");
}
@Test
public void test(){
  Book book= (Book) context.getBean("book");
  System.out.println(book.getAuthor().hashCode());
  System.out.println(book.getAuthor().hashCode());
  System.out.println(book.getPrototypeAuthor().hashCode());
  System.out.println(book.getPrototypeAuthor().hashCode());

测试结果

从结果中可以发现,只有从 BeanFactory 中获取得到的 Author 实例是不同的。

这种实现把应用与 Spring 框架绑定在了一起,是否有更好的解决方案呢?有,就是注入方法。

1 注入方法

Spring 容器依赖于 CGLib 库,所以可以在运行期动态操作 Class 的字节码,比如动态地创建 Bean 的子类或实现类。

BookInterface 接口:

public interface BookInterface {
  Author getAuthor();
}

XML 配置:

<!-- 方法注入-->
<bean id="author" class="net.deniro.spring4.bean.Author" scope="prototype"
   p:name="毛姆"
    />
<bean id="book2" class="net.deniro.spring4.bean.BookInterface">
  <lookup-method name="getAuthor" bean="author"/>
</bean>

单元测试:

BookInterface book= (BookInterface) context.getBean("book2");
Assert.assertEquals("毛姆",book.getAuthor().getName());
Assert.assertTrue(book.getAuthor().hashCode()!=book.getAuthor().hashCode());

通过这种配置方式,就可以为接口提供动态实现啦,而且这样返回的 Bean 都是新的实例。

所以,如果希望在一个 singleton Bean 中获取一个 prototype Bean 时,就可以使用 lookup 来实现注入方法。

2 替换方法

在 Spring 中,可以使用某个 Bean 的方法去替换另一个 Bean 的方法。

假设 Book 中有一个 getName() 方法,用于获取书名:

/**
 * 书名
 */
private String name;
public String getName() {
  return name;
}

我们现在新建一个 Bean,它实现了 MethodReplacer 接口,用于替换 Book 中的 getName() 方法:

public class Book4 implements MethodReplacer {
  @Override
  public Object reimplement(Object obj, Method method, Object[] args) throws Throwable {
    return "活着";
  }
}

配置:

<bean id="book3" class="net.deniro.spring4.bean.Book"
   p:name="灿烂千阳">
  <replaced-method name="getName" replacer="book4"/>
</bean>
<bean id="book4" class="net.deniro.spring4.bean.Book4"/>

测试:

Book book= (Book) context.getBean("book3");
assertEquals("活着", book.getName());

总结

以上所述是小编给大家介绍的Spring 框架中注入或替换方法实现,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

(0)

相关推荐

  • Spring注入Date类型的三种方法总结

    Spring注入Date类型的三种方法总结 测试Bean: public class DateBean { private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } 方式1:利用SimpleDateFormat的构造方法注入 <?xml version="1.0&quo

  • spring hibernate实现动态替换表名(分表)的方法

    1.概述 其实最简单的办法就是使用原生sql,如 session.createSQLQuery("sql"),或者使用jdbcTemplate.但是项目中已经使用了hql的方式查询,修改起来又累,风险又大!所以,必须找到一种比较好的解决方案,实在不行再改写吧!经过3天的时间的研究,终于找到一种不错的方法,下面讲述之. 2.步骤 2.1 新建hibernate interceptor类 /** * Created by hdwang on 2017/8/7. * * hibernate拦

  • spring+springmvc整合mabytis时mapper注入失败问题解决方法

    好久不搭架构,今天使用spring+springmvc整合mabytis的时候,坑爹的两个问题发生了. 花了一晚上解决这两个问题.现在将错误经验总结分享下,避免以后遇到坑继续往里跳. 1. 单元测试的时候,单元测试失败报错: A ServletContext is required to configure default servlet handling 十月 28, 2016 9:03:33 下午 org.springframework.context.support.GenericAppl

  • JSP开发之Spring方法注入之替换方法实现

    JSP开发之Spring方法注入之替换方法实现 Spring提供了一种替换方法实现的机制,可以让我们改变某个bean某方法的实现.打个比方我们有一个bean,其中拥有一个add()方法可以用来计算两个整数的和,但这个时候我们想把它的实现逻辑改为如果两个整数的值相同则把它们相乘,否则还是把它们相加,在不改变或者是不能改变源码的情况下我们就可以通过Spring提供的替换方法实现机制来实现这一要求. 替换方法实现机制的核心是MethodReplacer接口,其中定义了一个reimplement ()方

  • 因Spring AOP导致@Autowired依赖注入失败的解决方法

    发现问题: 之前用springAOP做了个操作日志记录,这次在往其他类上使用的时候,service一直注入失败,找了网上好多内容,发现大家都有类似的情况出现,但是又和自己的情况不太符合.后来总结自己的情况发现:方法为private修饰的,在AOP适配的时候会导致service注入失败,并且同一个service在其他的public方法中就没有这种情况,十分诡异. 解决过程: 结合查阅的资料进行了分析:在org.springframework.aop.support.AopUtils中: publi

  • springboot注入servlet的方法

    问:有了springMVC,为什么还要用servlet?有了servlet3的注解,为什么还要使用ServletRegistrationBean注入的方式? 使用场景:在有些场景下,比如我们要使用hystrix-dashboard,这时候就需要注入HystrixMetricsStreamServlet(第三方的servlet),该servlet是hystrix的组件. 一.代码 1.TestServlet(第一个servlet) package com.xxx.secondboot.servle

  • Spring 框架中注入或替换方法实现

    无状态 Bean 的作用域是 singleton 单实例,如果我们向 singleton 的 Bean A 注入 prototype 的 Bean B,并希望每次调用 Bean A 的 getBeanB() 时都能返回一个新的 Bean B ,这样的要求使用传统的注入方式是无法实现的 . 因为 singleton 的 Bean 注入关联 Bean 的动作只发生一次,虽然 Bean B 的作用域是 prototype 类型,但通过 getBeanB() 返回的对象还是最开始注入的那个 bean B

  • Spring框架依赖注入方法示例

    在阅读这篇文章之前,大家可以先参阅<理解Spring中的依赖注入和控制反转>一文,了解下依赖注入和控制反转的相关内容. 三种依赖注入的方式 属性注入,通过setter方法注入bean的属性值或依赖的对象 构造注入 工厂方法注入(很少使用) 例子 这里我们使用了spring-4.3.2,maven配置文件 <dependency> <groupid>org.springframework</groupid> spring-core</artifactid

  • 深入浅出讲解Spring框架中依赖注入与控制反转及应用

    目录 一. 概念: 1. 使用前: 2. 使用后: 二. 理解控制反转(Ioc): 三. IoC的应用方法 一. 概念: 依赖注入(Dependency Injection,DI)与控制反转(IoC)的含义相同,只不过是从两个角度描述的同一个概念.对于一个Spring初学者来说,这两种称呼都很难理解,我们通过简单的语言来描述这两个概念. 使用对比: 1. 使用前: 当某个Java对象(调用者)需要调用另一个Java对象(被调用者,就是被依赖对象)时,在传统模式下,调用者通常会采用"new被调用者

  • Spring框架中IoC容器与DI依赖注入教程

    目录 一.Spring 是什么 1.1 什么是容器 1.2 什么是 IoC 二.理解 IoC 2.1 传统程序开发的问题 2.2 分析 2.3 控制反转式程序开发 2.4 对比总结规律 2.5 理解 Spring IoC 三.DI 概念说明 四.总结 一.Spring 是什么 我们通常所说的 Spring 指的是 Spring Framework (Spring 框架),它是⼀个开源框架,有着活跃而庞大的社区,这就是它之所以能长久不衰的原因.Spring ⽀持⼴泛的应⽤场景,它可以让 Java

  • 深入理解Java的Spring框架中的IOC容器

    Spring IOC的原型 spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功完成了依赖的反转:从主类的对依赖的主动管理反转为了spring容器对依赖的全局控制. 这样做的好处是什么呢? 当然就是所谓的"解耦"了,可以使得程序的各模块之间的关系更为独立,只需要spring控制这些模块之间的依赖关系并在容器启动和初始化的过程中将依据这些依赖关系创建.管理和维护这些模块就好,如果需要改变模块间的依赖关系的话,甚至都不需要改变程序代码,只需要将

  • Spring框架中 @Autowired 和 @Resource 注解的区别

    Spring框架中 @Autowired 和 @Resource 注解的区别 在 spring 框架中,除了使用其特有的注解外,使用基于 JSR-250 的注解,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释. 首先,咱们简单了解 @PostConstruct 和 @PreDestroy 注释: 为了定义一个 bean 的安装和卸载,我们可以使用 init-method 和 destroy-method 参数简单的声明一下 ,其中 init-meth

  • 详解Spring Boot中MyBatis的使用方法

    orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中可以根据需求灵活使用.发现一个有趣的现象:传统企业大都喜欢使用hibernate,互联网行业通常使用mybatis. hibernate特点就是所有的sql都用Java代码来生成,不用跳出程序去写(看)sql,有着编程的完整性,发展到最顶端就是spring data jpa这种模式了,基本上根据

  • 设计模式在Spring框架中的应用汇总

    这篇文章主要介绍了设计模式在Spring框架中的应用汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在开始正文之前,请你先思考几个问题: 你项目中有使用哪些 GOF 设计模式 说一说 GOF 23 种设计模式的设计理念 说说 Spring 框架中如何实现设计模式 假设我是面试官问起了你这些面试题,你该如何回答呢,请先思考一分钟. 好的,我们开始进入正题.设计模式实践里面提供了许多经久不衰的解决方案和最佳方案.这里,GOF 设计模式主要分为三

  • Spring框架中一个有用的小组件之Spring Retry组件详解

    1.概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力.这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助. 在本文中,我们将看到使用Spring Retry的各种方式:注解.RetryTemplate以及回调. 2.Maven依赖 让我们首先将spring-retry依赖项添加到我们的pom.xml文件中: <dependency> <groupId>org.springframework.retry</groupI

随机推荐