`
kingxss
  • 浏览: 973348 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring通过父类注入公用属性的技巧

阅读更多

XML配置方式提取父类       

      在使用Spring + Hibernate框架,或者SSH2等框架的时候,在开发中只有一个基本的DAO是现在的非常流行的做法。然后,在看过多份这种代码以后,都是在每个业务类中声明了一个DAO属性,并且在Bean配置中,对每个业务类分别注入DAO。具体情形示例如下:

BaseDAO代码:

public class BaseDAO {
	public String service() {
		return "Success!";
	}
}

Services代码:

//第一个业务类
public class ServiceA {
	public String service() {
		return baseDAO.service();
	}
	
	protected BaseDAO baseDAO;

	public void setBaseDAO(BaseDAO baseDAO) {
		this.baseDAO = baseDAO;
	}
}

//第二个业务类
public class ServiceB {
	public String service() {
		return baseDAO.service();
	}
	
	protected BaseDAO baseDAO;

	public void setBaseDAO(BaseDAO baseDAO) {
		this.baseDAO = baseDAO;
	}
}

  Spring的Bean配置如下:

<bean id="baseDAO" class="com.watson.BaseDAO" />
<bean id="serviceA" class="com.watson.ServiceA">
	<property name="baseDAO" ref="baseDAO" />
</bean>
<bean id="serviceB" class="com.watson.ServiceB">
	<property name="baseDAO" ref="baseDAO" />
</bean>

 这样的做法是现在的主流。这样做不是说那里错了,还是那句老话:这样做肯定不优美,谁让人有时候是一根筋呢?

 能够想到的办法是用一个父类来包含一些业务层公用的业务逻辑和属性。所以可以将上面的代码和配置。

Services代码改写如下:

//所有业务类的父类
public class BaseService {
	protected BaseDAO baseDAO;

	public void setBaseDAO(BaseDAO baseDAO) {
		this.baseDAO = baseDAO;
	}
}
//第一个业务类
public class ServiceA extends BaseService  {
	public String service() {
		return baseDAO.service();
	}
}
//第二个业务类
public class ServiceB extends BaseService  {
	public String service() {
		return baseDAO.service();
	}
}

 Spring的Bean配置改写如下:

<bean id="baseDAO" class="com.watson.BaseDAO" />
<bean id="BaseService" class="com.watson.BaseService" />
	<property name="baseDAO" ref="baseDAO" />
</bean>
<bean id="serviceA" class="com.watson.ServiceA" />
<bean id="serviceB" class="com.watson.ServiceB" />

 这样一来是不简洁了很多?尤其在实际项目有太多Bean的时候。然后,这里不会达到我们预想的结果,因为这里会出现如下的错误:

exception:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
......
root cause:
java.lang.NullPointerException:......

而出错代码就是每个业务中调用baseDAO的那行代码。这说明注入失败了。翻阅Spring的Bean注入详解之后,很快就可以找应该设置子类Bean配置的parent属性。所以这里可以修改设置。

 Spring的Bean配置改写如下:

<bean id="baseDAO" class="com.watson.BaseDAO" />
<bean id="BaseService" class="com.watson.BaseService" />
	<property name="baseDAO" ref="baseDAO" />
</bean>
<bean id="serviceA" class="com.watson.ServiceA" parent="baseService" />
<bean id="serviceB" class="com.watson.ServiceB" parent="baseService" />

这个时候再运行,就不会报错了。原理是:在Spring的子类Bean配置中,其parent属性作用是指定其父类,并继承父类的注入属性。不仅如此,子类还可以修改或者覆盖父类的属性值。例如上述代码中的子类修改父类的baseDAO到属性:

<bean id="BaseService" class="com.watson.BaseService" />
	<property name="baseDAO" ref="baseDAO" />
</bean>
<bean id="serviceA" class="com.watson.ServiceA" parent="baseService" />
<property name="baseDAO" ref="baseDAO2" />
</bean>

而对于父类的List等集合属性,子类可以继承父类的值,并且在其基础上进行增加新的值:

<bean id="BaseService" class="com.watson.BaseService" />
	<property name="listValue">  
		<list>  
			<value>listValue1</value>  
			<value>listValue2</value>  
		</list>  
	</property> 
</bean>
<bean id="serviceA" class="com.watson.ServiceA" parent="baseService" />
	<property name="listValue">  
		<list>  
			<value>listValue3</value>  
			<value>listValue4</value>  
		</list>  
	</property> 
</bean>

 

Annotation方式提取父类

上面的方法是在XML配置文件中进行的配置。而对现在Spring3流行的Annotation方式,其实更加的方便,完整示例如下:

BaseDAO代码:

@Component
public class BaseDAO {
	public String service() {
		return "Success!";
	}
}

Services代码:

//所有业务类的父类
public class BaseService {
	@Autowired
	protected BaseDAO baseDAO;
}

//第一个业务类
@Component
public class ServiceA extends BaseService  {
	public String service() {
		return baseDAO.service();
	}
}
//第二个业务类
@Component
public class ServiceB extends BaseService  {
	public String service() {
		return baseDAO.service();
	}
}

Action层代码:

@Controller
@RequestMapping(value = "/testaction")
public class TestAction {
	@Autowired
	private ServiceA service;
	
	@RequestMapping(value = "/")
	public @ResponseBody String home(Model model) {
		return service.service();
	}
}

这里根本就不需要进行parent属性子类的配置,可以完美的提取父类,并且可以顺利的使用父类的公用属性。至于原理,没有去看源码的处理方式,估计和上述XML配置是异曲同工的,只是在这里增加了对父类的检测。

分享到:
评论
1 楼 flyfeifei66 2018-07-18  
baseservice、dao代码是同一个,但是实例配置多个,比如增加第二个
<bean id="BaseService2" class="com.watson.BaseService" /> 
    <property name="baseDAO2" ref="baseDAO2" /> 
</bean>

<bean id="baseDAO2" class="com.watson.BaseDAO" >
数据源属性
</bean>
这样完成不同的基类service访问不同的数据源,这样做可以吗?

相关推荐

    Spring使用@Autowired为抽象父类注入依赖代码实例

    Spring使用@Autowired为抽象父类注入依赖代码实例 Spring框架中,使用@Autowired注解可以将依赖项注入到Bean中,但是当我们需要将依赖项注入到抽象父类时,会遇到一些问题。如果我们直接使用@Autowired注解在抽象...

    用反射的方式获取父类中的所有属性和方法

    在Java编程语言中,反射(Reflection)是一种强大的工具,它允许程序在运行时检查和操作对象的内部结构,包括类的属性、方法以及构造器。...通过上述步骤,你可以有效地利用反射获取和操作类的父类属性和方法。

    spring 普通属性注入

    在Spring框架中,属性注入是核心特性之一,它允许我们通过依赖注入(Dependency Injection, DI)来管理对象的属性,而不是让对象自行创建或查找它们的依赖。这有助于提高代码的可测试性、可维护性和解耦性。下面将...

    Spring boot工具类静态属性注入及多环境配置详解

    Spring Boot工具类静态属性注入及多环境配置详解 Spring Boot工具类静态属性注入是指使用Spring Boot框架时,如何将配置信息注入到工具类的静态变量中,以便在程序中使用这些配置信息。这种方式可以方便地在不同的...

    Spring注解注入属性

    ### Spring注解注入属性 #### 一、传统方式与注解方式对比 在Spring框架中,依赖注入(DI)是一种核心的设计模式,用于促进松耦合的系统设计,使得组件之间的依赖关系可以在运行时动态地建立,而不是在编译时硬...

    Spring三种注入方式(三)

    在Spring框架中,依赖注入(Dependency Injection,简称DI)是一种重要的设计模式,它使得对象之间的耦合...通过理解并熟练运用构造器注入、设值注入和接口注入,开发者可以更好地利用Spring框架进行企业级应用的开发。

    spring工厂属性注入

    通过这种方式,即使对象的创建涉及到复杂的逻辑,Spring也能通过工厂bean进行控制并管理对象的生命周期,同时保持属性注入的能力。在实际应用中,这可能涉及到数据库连接、线程池等需要特殊初始化的资源。 总结一下...

    spring 设值注入

    在Spring框架中,设值注入(Value Injection)是一种将外部属性值注入到bean对象中的方法。它是通过在bean的配置元数据中定义属性值来实现的,这些值会在bean实例化时自动设置。设值注入是Spring依赖注入...

    day38 17-Spring的Bean的属性注入:注解方式

    在Spring框架中,Bean的属性注入是核心功能之一,它允许开发者在不编写代码的情况下配置对象的依赖关系。本文将详细讲解使用注解方式进行Bean属性注入的方法,以及相关的源码和工具应用。 首先,让我们了解Spring中...

    关于spring boot中几种注入方法的一些个人看法

    @Resource 可以用在方法、属性、类上,通过 CommonAnnotationBeanPostProcessor 类实现依赖注入,与 @Autowired 一致。但可以指定 name 属性来指定 beanName,但如果 name 对应的 bean 不存在,则会抛出异常。 3. @...

    day38 11-Spring的Bean的属性的注入:对象属性

    - Spring允许从不同来源(如环境变量、系统属性、配置文件)注入属性,通过`@Value`的`${}`语法引用这些值。 - Spring还支持Profile特性,可以在不同的运行环境中使用不同的配置。 6. **最佳实践** - 避免过多的...

    day38 12-Spring的Bean的属性的注入:名称空间p

    在Spring框架中,Bean的属性注入是核心功能之一,它允许我们通过配置文件或注解来设置Bean实例的属性值,使得对象的初始化更加灵活。本文将深入探讨Spring中的"名称空间p",这是一种用于配置Bean属性注入的方式,...

    spring的注入方式

    在Spring框架中,依赖注入(Dependency Injection,简称DI)是一种重要的设计模式,它使得对象间的依赖关系得以解耦,提高了代码的可测试性和可维护...通过实践和理解这些例子,你可以更好地掌握Spring的依赖注入机制。

    spring的setter注入和构造注入(XML讲解以及常见错误)

    通过在类中定义setter方法,Spring容器可以在创建对象后,通过这些setter方法设置对象的属性值。以下是一个简单的例子: ```java public class User { private String name; public void setName(String name) {...

    知识共享-Spring注入属性值案例(雷惊风).

    ### Spring框架中的属性值注入详解 #### 一、Spring框架简介 Spring框架是一个开源的Java平台,用于构建企业级应用程序。它提供了全面的基础架构支持,包括依赖注入(Dependency Injection, DI)、面向切面编程...

    Spring Ioc(依赖注入)入门例子--属性注入

    在本例“Spring Ioc(依赖注入)入门例子--属性注入”中,我们将关注如何通过属性注入来管理依赖。 属性注入是指Spring容器将一个对象的属性值设置为另一个对象的引用。这通常用于将服务对象注入到需要使用它们的...

    spring各种属性的注入

    通过本文档的学习,我们可以了解到Spring框架中各种属性注入的基本方法。这些方法不仅限于基本数据类型和集合类型,还包括Bean之间的引用注入,这些功能大大增强了Spring框架的灵活性和扩展性,使得开发人员能够更加...

    day38 14-Spring的Bean的属性的注入:集合属性的注入

    在Spring框架中,Bean的属性注入是核心功能之一,它允许我们通过配置文件或注解来设置Bean的属性值,从而实现对象的依赖管理。在本主题“day38 14-Spring的Bean的属性的注入:集合属性的注入”中,我们将深入探讨...

    Spring学习笔记(8)----属性注入的方式

    在Spring框架中,属性注入是将外部配置的属性值注入到Bean对象中,使得对象可以在运行时根据配置动态地获取其依赖的属性。本篇学习笔记主要探讨了Spring中的属性注入方式,包括了传统的XML配置注入、注解式注入以及...

    Spring属性注入

    在Spring中,属性注入(Property Injection)是一种重要的功能,它允许开发者在不直接创建对象的情况下设置对象的属性,从而实现了松耦合和更好的可测试性。 **XML方式的属性注入** 1. **Set注入**:这是Spring ...

Global site tag (gtag.js) - Google Analytics