spring巧用继承解决bean的id相同的问题
来源:互联网 发布:我是未来 阿里云 编辑:程序博客网 时间:2024/05/16 12:18
先感叹一下:最近的项目真的很奇葩!!!
需求是这样的:我们的项目中引用了两个jar包,这两个jar包是其他项目组提供的,不能修改!
奇葩的是:这两个jar中都需要引用方提供一个相同id的bean,而bean的定义却是不同的,也就是虽然id相同,但他们对应的却是两个不同的java类,导致出现的问题是:该id对应的java类满足了第一个jar包的要求,则不能满足第二个jar包的要求,满足了第二个jar包的要求,则不能满足第一个jar包的要求,导致spring容器在启动时就报错。
那么,该怎么解决该问题呢?如何做才能符合两个jar包的需求呢?经过仔细思考:发现通过java类的继承可以巧妙的实现该需求,现示例如下:
spring主配置文件:
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><import resource="classpath*:app1.xml"/><import resource="classpath*:app2.xml"/><import resource="classpath:appContext1.xml"/><!-- <import resource="classpath:appContext2.xml"/> --></beans>
其中:app1.xml和app2.xml是两个jar包app1.jar和app2.jar中对应的spring配置文件
app1.jar和app2.jar中主要就有一个java编译好后的class文件和一个配置文件:
其中app1.jar中的java文件和配置文件分别为:
Test1.java
package mypackage;public class Test1 {private Object obj;public Object getObj() {return obj;}public void setObj(Object obj) {this.obj = obj;}@Overridepublic String toString() {if(!this.getObj().getClass().getName().equals("mypackage.Obj1")){try {throw new Exception();} catch (Exception e) {System.err.println("test1--->mypackage.Test1依赖的obj类型错误,注入的不是mypacke.Obj1");}}System.out.println("package.Test1");return "package.Test1";}}
app1.xml
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><bean id="test1" class="mypackage.Test1"><property name="obj"><ref bean="mybean"/></property></bean></beans>
app2.jar中的java类和配置文件分别为:
Test2.java
package mypackage;public class Test2 {private Object obj;public Object getObj() {return obj;}public void setObj(Object obj) {this.obj = obj;}@Overridepublic String toString() {if(!this.getObj().getClass().getName().equals("mypackage.Obj2")){try {throw new Exception();} catch (Exception e) {System.err.println("test2--->mypackage.Test2依赖的obj类型错误,注入的不是mypacke.Obj2");}}System.out.println("package.Test2");return "package.Test2";}}
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><bean id="test2" class="mypackage.Test2"><property name="obj"><ref bean="mybean"/></property></bean></beans>
其中:mybean是需要引用方提供的,这两个jar中需要引用方提供的bean的id都是一样的,这就导致了文章开始所提到的的问题。
测试程序:
package mypackage;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");/*System.out.println(((Test1)context.getBean("child1")).getObj().getClass().getName());System.out.println(((Test1)context.getBean("child2")).getObj().getClass().getName());*/System.out.println(((Test1)context.getBean("test1")).getObj().getClass().getName());System.out.println(((Test2)context.getBean("test2")).getObj().getClass().getName());}}
运行得到的两个bean是相同的bean,不符合要求!!
解决方案:
引进两个子类Child1和Child2,分别继承jar包需要的Test1和Test2
Child1.java
package mypackage;public class Child1 extends Test1 {private Object obj;public Object getObj() {return obj;}public void setObj(Object obj) {this.obj = obj;}@Overridepublic String toString() {if(!this.getObj().getClass().getName().equals("mypackage.Hello")){try {throw new Exception();} catch (Exception e) {System.err.println("child1--->mypackage.Test依赖的obj注入的类型错误,注入的不是mypacke.Hello");}}return "package.Test1";}}
Child2.java
package mypackage;public class Child2 extends Test2 {private Object obj;public Object getObj() {return obj;}public void setObj(Object obj) {this.obj = obj;}@Overridepublic String toString() {if(!this.getObj().getClass().getName().equals("mypackage.World")){try {throw new Exception();} catch (Exception e) {System.err.println("child2--->mypackage.Test2依赖的obj注入的类型错误,注入的不是mypacke.World");}}return "package.Test2";}}
添加一个新的spring辅助配置文件:
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><bean id="obj1" class="mypackage.Obj1"></bean><bean id="obj2" class="mypackage.Obj2"></bean><bean id="mybean1" class="mypackage.Obj2"></bean><bean id="mybean2" class="mypackage.Obj2"></bean><bean id="child1" class="mypackage.Child1"><property name="obj"><ref bean="mybean1"/></property></bean><bean id="child2" class="mypackage.Child2"><property name="obj"><ref bean="mybean2"/></property></bean></beans>
在spring主配置文件做修改如下:
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"><!-- <import resource="classpath*:app1.xml"/><import resource="classpath*:app2.xml"/> --><import resource="classpath:appContext1.xml"/><import resource="classpath:appContext2.xml"/> </beans>
package mypackage;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//System.out.println(context);/*System.out.println(((Test2)(context.getBean("test2"))).getObj().getClass().getName());System.out.println(((Test)(context.getBean("test"))).getObj().getClass().getName());*///System.out.println(context.getBean("mybean").getClass().getName());System.out.println(context.getBean("child1"));System.out.println(context.getBean("child2"));/*System.out.println(context.getBean("mypackage.Hello"));System.out.println(context.getBean("mypackage.Hello#1"));*/}}
运行得到:获取的是不同的bean,也就是间接实现了两个jar包中需要提供同名id的bean,但bean对应的java类是不同的java类的需求!
总结:实际上就是面向对象的lisp原则,就是里氏替换原则,具体点就是凡是父类出现的地方,都可以用子类来代替!
例子很简单,但是能说明问题。
github上源码地址:https://github.com/iamzken/kuaiqian/tree/master/spring-same-id-bean-test
- spring巧用继承解决bean的id相同的问题
- 关于spring中处理相同id的bean的问题
- Spring处理id相同的bean
- Spring处理id相同的bean
- Spring bean id相同覆盖的问题解决
- Spring bean id相同覆盖的问题解决
- Spring处理id相同的bean
- Spring bean id相同覆盖的问题解决
- Spring bean id相同引发的故障
- 解决spring中不同配置文件中存在name或者id相同的bean可能引起的问题
- 解决spring中不同配置文件中存在name或者id相同的bean可能引起的问题
- 解决spring中不同配置文件中存在name或者id相同的bean可能引起的问题
- Spring Bean的继承
- spring bean工厂和bean的id
- spring的bean的继承
- Spring的bean的继承
- Spring中bean的继承
- spring中bean的继承
- oracle 求两个时间点直接的分钟、小时数
- 游戏中常见的洗牌算法
- SLRequest
- git学习笔记(一)
- UTF-8和GBK互转
- spring巧用继承解决bean的id相同的问题
- Realm简单入门(转载)
- 正则表达式
- Code Convention
- C++技巧之operator操作符
- popupwindow返回键处理
- Service的基本使用
- Android开发中intent-startActivityForResult
- Json转换利器Gson二、GsonBuilder