根据不同属性类型动态获取不同bean



第一步:SpringContextUtil工具类直接复制到项目中

import java.util.ArrayList;

import java.util.Collection;

import java.util.HashMap;

import java.util.Map;

import org.apache.commons.lang.ArrayUtils;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

 

public class SpringContextUtil implements ApplicationContextAware {

private static ApplicationContext applicationContext; // Spring应用上下文环境

 

/**

 * 实现ApplicationContextAware接口的回调方法,设置上下文环境

 * @param applicationContext

 * @throws BeansException

 */

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

SpringContextUtil.applicationContext = applicationContext;

}

 

/**

 * @return ApplicationContext

 */

public static ApplicationContext getApplicationContext() {

return applicationContext;

}

 

/**

 * 获取对象

 *

 * @param name

 * @return Object 一个以所给名字注册的bean的实例

 * @throws BeansException

 */

public static Object getBean(String name) throws BeansException {

return applicationContext.getBean(name);

}

 

/**

 * 获取类型为requiredType的对象

 * 如果bean不能被类型转换,相应的异常将会被抛出(BeanNotOfRequiredTypeException)

 *

 * @param name

 *            bean注册名

 * @param requiredType

 *            返回对象类型

 * @return Object 返回requiredType类型对象

 * @throws BeansException

 */

public static Object getBean(String name, Class<?> requiredType) throws BeansException {

return applicationContext.getBean(name, requiredType);

}

 

public static Object getBean(Class<?> requiredType) throws BeansException {

String[] names = applicationContext.getBeanNamesForType(requiredType);

if (ArrayUtils.isEmpty(names)) {

throw new IllegalArgumentException("没有找到Bean,类型:" + requiredType.getName());

}

return applicationContext.getBean(names[0]);

}

 

public static Collection<Object> getBeans(String... names) throws BeansException {

Collection<Object> beans = new ArrayList<Object>();

for (String name : names) {

beans.add(applicationContext.getBean(name));

}

return beans;

}

 

public static Map<?, ?> getBeans(Class<?> requiredType) throws BeansException {

Map<String, Object> beans = new HashMap<String, Object>();

String[] names = applicationContext.getBeanNamesForType(requiredType);

for (String name : names) {

beans.put(name, applicationContext.getBean(name));

}

return beans;

}

 

/**

 * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true

 *

 * @param name

 * @return boolean

 */

public static boolean containsBean(String name) {

return applicationContext.containsBean(name);

}

 

/**

 * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。

 * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)

 *

 * @param name

 * @return boolean

 * @throws NoSuchBeanDefinitionException

 */

public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {

return applicationContext.isSingleton(name);

}

 

/**

 * @param name

 * @return Class 注册对象的类型

 * @throws NoSuchBeanDefinitionException

 */

public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {

return applicationContext.getType(name);

}

 

/**

 * 如果给定的bean名字在bean定义中有别名,则返回这些别名

 *

 * @param name

 * @return

 * @throws NoSuchBeanDefinitionException

 */

public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {

return applicationContext.getAliases(name);

}

}

第二步:spring配置文件中配置

<!-- 建议第一行,最起码要在应用的类前面加载 -->

<bean id="springContextUtil" class="com.cn.demo.SpringContextUtil" />

第三步:类中应用的方式

SpringContextUtil.getBean(bean的id);

说明:

到上面可以说是已经结束了,但是,对于一些新手来说,恐怕没那么简单,废话少说,直接简单的demo

 

第一步:创建一个共有父类抽象类,里面是用到的一些共有方法或者参数

public abstract class Demo {

public void demo(){

System.out.println("demo");

}

}

第二步:实际执行的类

Demo1类:

public class Demo1 extends Demo{

public void demo(){

System.out.println("demo1");

}

}

 

Demo2类:

public class Demo2 extends Demo{

public void demo(){

System.out.println("demo2");

}

}

第三步:调用者

public class Demo3 {

public void test(String beanName){

Demo demo = (Demo)SpringContextUtil.getBean(beanName);

demo.demo();

}

}

第四步:配置文件(applicationContext-config.xml)

<!-- 建议第一行,最起码要在应用的类前面加载 -->       

<bean id="springContextUtil" class="com.cn.demo.SpringContextUtil" />

 

<bean id="demo3" class="com.cn.demo.Demo3"/>

<bean id="demo1" class="com.cn.demo.Demo1"/>

<bean id="demo2" class="com.cn.demo.Demo2"/>

 

第五步:测试类

public class Test {

public static void main(String[] args) {

ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[]{"classpath*:applicationContext-config.xml"});

Demo3 d = (Demo3)appContext.getBean("demo3");

d.test("demo1");

appContext.start();

}

}

说明:

经过上面案例,是不是明白了许多,建议直接复制到测试项目中,或者直接黏贴到项目中,测试下看看就可以了,实际用的话,结合自己的项目需求,入座对号就可以了,原理都是一样的

在 Java 中实现两个不同bean 属性复制,有以下几种常见方法: ### 使用 `org.springframework.beans.BeanUtils` 工具类 `org.springframework.beans.BeanUtils` 提供了 `copyProperties` 方法,可将一个 bean属性值复制到另一个 bean 中。使用该方法的前提是复制的 bean 的字段要完全包含在被复制的 bean 中。示例代码如下: ```java import org.springframework.beans.BeanUtils; public class BeanCopyExample { public static void main(String[] args) { SourceBean source = new SourceBean(); source.setName("John"); source.setAge(30); TargetBean target = new TargetBean(); BeanUtils.copyProperties(source, target); System.out.println(target.getName()); System.out.println(target.getAge()); } } class SourceBean { private String name; private int age; // Getters and Setters public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } class TargetBean { private String name; private int age; // Getters and Setters public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } ``` ### 利用 Java 反射机制 基本思想是利用 Java 反射机制获得 beans 中的 setter 和 getter 方法,当发现两者属性名一致时就调用方法来获得和设置值。使用该方法的前提是两个 bean 对象必须属性名和类型一致,而且实现了 getter 和 setter 方法。示例代码如下: ```java import java.lang.reflect.Method; public class ReflectiveBeanCopy { public static void copyProperties(Object source, Object target) throws Exception { Class<?> sourceClass = source.getClass(); Class<?> targetClass = target.getClass(); for (Method sourceMethod : sourceClass.getMethods()) { if (sourceMethod.getName().startsWith("get")) { String propertyName = sourceMethod.getName().substring(3); Method targetSetMethod; try { targetSetMethod = targetClass.getMethod("set" + propertyName, sourceMethod.getReturnType()); Object value = sourceMethod.invoke(source); targetSetMethod.invoke(target, value); } catch (NoSuchMethodException e) { continue; } } } } public static void main(String[] args) throws Exception { SourceBean source = new SourceBean(); source.setName("John"); source.setAge(30); TargetBean target = new TargetBean(); copyProperties(source, target); System.out.println(target.getName()); System.out.println(target.getAge()); } } ``` ### 使用 BeanMapping 框架 BeanMapping 框架提供了一个简单的静态方法 `copyProperties`,将 source 中的赋值给 target 中名称相同且可以赋值的类型中去,类似于 Spring 的 `BeanUtils`。示例代码如下: ```java public class BeanMappingExample { public static void main(String[] args) { SourceBean source = new SourceBean(); source.setName("John"); source.setAge(30); TargetBean target = new TargetBean(); BeanMapping.copyProperties(source, target); System.out.println(target.getName()); System.out.println(target.getAge()); } } class BeanMapping { public static void copyProperties(final Object source, Object target) { // 实现细节省略 } } ``` ### 使用 ASM 的字节码技术 使用 ASM 的字节码技术,动态生成类,实现属性的复制,生成的类速度比 Spring 的 `BeanUtils` 快,初始化也更快。示例代码如下: ```java // 假设已经有动态生成的类 public final class Generator$1$Copier implements Copier { public Generator$1$Copier() { } @Override public void copy(Object var1, Object var2) { SourceBean u1 = (SourceBean) var1; TargetBean u2 = (TargetBean) var2; u2.setName(u1.getName()); u2.setAge(u1.getAge()); } } interface Copier { void copy(Object source, Object target); } public class ASMBeanCopyExample { public static void main(String[] args) { SourceBean source = new SourceBean(); source.setName("John"); source.setAge(30); TargetBean target = new TargetBean(); Generator$1$Copier copier = new Generator$1$Copier(); copier.copy(source, target); System.out.println(target.getName()); System.out.println(target.getAge()); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值