使用Cglib的BeanCopier

 当源和目标类的属性类型不同时,不能拷贝该属性,此时我们可以通过实现Converter接口来自定义转换器:

源类和目标类:

Java代码

public class AccountEntity {  
    private int id;  
    private Timestamp createTime;  
    private BigDecimal balance;  
    // Getters and setters are omitted  
}  

Java代码

public class AccountDto {  
    private int id;  
    private String name;  
    private String createTime;  
    private String balance;  
    // Getters and setters are omitted  
}  

1. 不使用Converter
 

Java代码

public class BeanCopierConverterTest {  
  
    @Test  
    public void noConverterTest() {  
        AccountEntity po = new AccountEntity();  
        po.setId(1);  
        po.setCreateTime(new Timestamp(10043143243L));  
        po.setBalance(BigDecimal.valueOf(4000L));  
        BeanCopier copier = BeanCopier.create(AccountEntity.class, AccountDto.class, false);  
        AccountDto dto = new AccountDto();  
        copier.copy(po, dto, null);  
        Assert.assertNull(dto.getCreateTime()); // 类型不同,未拷贝  
        Assert.assertNull(dto.getBalance()); // 类型不同,未拷贝  
    }  
} 

2. 使用Converter

基于目标对象的属性出发,如果源对象有相同名称的属性,则调一次convert方法:
 

Java代码

package net.sf.cglib.core;  
  
public interface Converter {  
    // value 源对象属性,target 目标对象属性类,context 目标对象setter方法名  
    Object convert(Object value, Class target, Object context);  
} 

Java代码

@Test  
public void converterTest() {  
    AccountEntity po = new AccountEntity();  
    po.setId(1);  
    po.setCreateTime(Timestamp.valueOf("2014-04-12 16:16:15"));  
    po.setBalance(BigDecimal.valueOf(4000L));  
    BeanCopier copier = BeanCopier.create(AccountEntity.class, AccountDto.class, true);  
    AccountConverter converter = new AccountConverter();  
    AccountDto dto = new AccountDto();  
    copier.copy(po, dto, converter);  
    Assert.assertEquals("2014-04-12 16:16:15", dto.getCreateTime());  
    Assert.assertEquals("4000", dto.getBalance());  
}  
  
static class AccountConverter implements Converter {  
  
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  
    @SuppressWarnings("rawtypes")  
    @Override  
    public Object convert(Object value, Class target, Object context) {  
        if (value instanceof Integer) {  
            return (Integer) value;  
        } else if (value instanceof Timestamp) {  
            Timestamp date = (Timestamp) value;  
            return sdf.format(date);  
        } else if (value instanceof BigDecimal) {  
            BigDecimal bd = (BigDecimal) value;  
            return bd.toPlainString();  
        }  
        return null;  
    }  
}  

注:一旦使用Converter,BeanCopier只使用Converter定义的规则去拷贝属性,所以在convert方法中要考虑所有的属性。

参考:

     iteye.com/blog/czj4451-2044101

使用CGLIB创建代理对象的主要步骤如下: 1. 定义一个类,并实现一个接口(或者继承一个类)作为目标类。 2. 在目标类中,定义一个方法。 3. 创建一个MethodInterceptor对象,用于拦截目标方法的执行。 4. 使用Enhancer类创建代理对象,设置目标类、MethodInterceptor对象和其他相关参数。 5. 调用代理对象的方法,触发MethodInterceptor对象的intercept方法。 6. 在intercept方法中,可以通过MethodProxy对象调用目标方法,并在目标方法执行前后添加一些操作。 下面是一个示例代码: ```java public interface UserService { void addUser(String name, String password); } public class UserServiceImpl implements UserService { @Override public void addUser(String name, String password) { System.out.println("Add user: " + name); } } public class UserServiceInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before method: " + method.getName()); Object result = proxy.invokeSuper(obj, args); System.out.println("After method: " + method.getName()); return result; } } public class ProxyDemo { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserServiceImpl.class); enhancer.setCallback(new UserServiceInterceptor()); UserService userService = (UserService) enhancer.create(); userService.addUser("Alice", "123456"); } } ``` 运行上述代码,输出结果如下: ``` Before method: addUser Add user: Alice After method: addUser ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值