`

实现java bean的懒加载

    博客分类:
  • Java
阅读更多

hibernate的lazy懒加载:

只有我们在正真使用时,它才会发出SQL语句,给我们去查询,如果不使用对象则不会发SQL语句进行查询。

Hibernate中lazy(懒加载)的实现:
采用了第三方组件的库,这个库叫cglib.jar(比较流行),这个库对我们的类生成代理类(JDK的动态代理,只能对JDK中实现了接口的类进行代理),代理可以控制源对象并且可以对源对象的功能进行增强,而cglib.jar可以对类进行代理(cglib对我们的类进行继承,生成一个子类,这个子类作为代理类返回给你)。
只有你正真代理类的方法,则会查看你有没有加载目标对象,如果没有则会加载目标对象。

 

可是网上很少有文章描述java bean如何实现懒加载。

下面,我使用cglib实现java bean 的懒加载方式。

1、首先,创建一个User类, 有name、age、car字段,而car字段是大对象, 这时候可以让car字段以懒加载方式加载数据。

 

public class User {
	private String name;
	private int age;
	private Car car;

	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;
	}

	public Car getCar() {
		return car;
	}

	public void setCar(Car car) {
		this.car = car;
	}
}

 

public class Car {
	private String carName;
	private String type;
	public String getCarName() {
		return carName;
	}
	public void setCarName(String carName) {
		this.carName = carName;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
}

 

2、利用cglib,创建懒加载工厂类LazyloadFactory, 实现cglib 的MethodInterceptor接口

 

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class LazyloadFactory implements MethodInterceptor {
	private Object target;

	public LazyloadFactory(Object target) {
		this.target = target;
	}

	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		String methodName = method.getName();
		if (methodName.startsWith("get")) {
			//获取属性
			Field field = target.getClass().getDeclaredField(
					methodName.substring(3, methodName.length()).toLowerCase());
			//对大字段懒加载
			if(field.getType()== Car.class) {
				field.setAccessible(true);
				
				//打印要执行的方法
				System.out.println("懒加载------>执行" + method.getName());
				//延迟加载, 这里可以从数据库中获取数据,给属性赋值
				System.out.println("懒加载------>" + "加载大对象开始");
				Thread.sleep(1000);
				
				Car car = new Car();
				car.setCarName("京Q123456");
				car.setType("宝马");
				//给指定的属性赋值
				field.set(target, car);  
				System.out.println("懒加载------>" + "加载大对象完成");
			}
		}
		Object result = proxy.invoke(target, args);
		return result;
	}
}

 3、创建获取User的Service, 这样可以实现懒加载

import org.springframework.cglib.proxy.Enhancer;

public class UserService {
	public User getUser() {
		User user = new User();
		//先给其他字段赋值
		user.setName("suncht");
		user.setAge(20);
		//再给大字段赋值(懒加载)
		LazyloadFactory intercepter=new LazyloadFactory(user);       
		return (User) Enhancer.create(User.class,intercepter);
	}
}

 4、我们用测试类进行测试下, 运行时,很明显会感觉到getCar().getName()进行懒加载

public class Test {

	public static void main(String[] args) {
		UserService service = new UserService();
		User user = service.getUser();
		System.out.println(user.getName());
		System.out.println(user.getAge());
		System.out.println(user.getCar().getCarName());
	}
}

   

 结果如下:

suncht
20
懒加载------>执行getCar
懒加载------>加载大对象开始
懒加载------>加载大对象完成
京Q123456

 

分享到:
评论

相关推荐

    Spring bean 动态注册,jar包热替换

    Spring bean 一般通过配置文件和注解进行加载,如果要实现jar或class文件,动态实现spring bean 的动态加载,并通过UrlClassLoader完成jar和class文件的加载。可以实现jar的热替换。spring的bean动态加载则需要对...

    spring 重新动态加载数据库或xml中的bean,可以不用重启tomcat

    spring 重新动态加载数据库或xml中的bean,可以不用重启tomcat

    Spring多种加载Bean方式解析

    本篇文章主要介绍了Spring多种加载Bean方式解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    cn.rar_java xml to bea_java commonUt_xml to be_xml to bean

    很简单的几个类,实现XML向Bean和Bean向XML的双向解析,核心为java的类加载器;另还提供一些通用工具类

    spring框架技术+第2天+xmind思维导图

    容器中实现懒加载.dependsOn属性;depends-on 在正式的程序开始之前,要预先加载一部分内容.依赖注入三种方式【手动装配-非注解方式】;构造函数注入 index:可省略,参数下标,默认从0开始 name :可省略,...

    java源码包---java 源码 大量 实例

    两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将...

    JAVA_API1.6文档(中文)

    java.beans.beancontext 提供与 bean 上下文有关的类和接口。 java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 ...

    Spring加载Bean: AbstractBeanFactory.xmind

    Spring加载Bean: AbstractBeanFactory.xmind

    2024年Java高工面试题 2024年Java高工面试题 2024年Java高工面试题

    (2)然后筛选出非懒加载的单例Bean Definition 对象进行创建Bean,多实例的Bean会在每次获取Bean时利用Bean Definition去创建 (3)利用Bean definition创建Bean就是Bean的创建生命周期,包括:合并Bean Definition ...

    java源码包4

    两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将...

    JAVA上百实例源码以及开源项目

    两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将...

    JAVA上百实例源码以及开源项目源代码

    两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将...

    java源码包3

    两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将...

    java源码包2

    两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean中,用累加器,以对话状态存储起来,创建EJB对象,并将...

    Java 1.6 API 中文 New

    java.beans.beancontext 提供与 bean 上下文有关的类和接口。 java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java ...

    web.xml中servlet, bean, filter, listenr 加载顺序_动力节点Java学院整理

    主要介绍了web.xml中servlet, bean, filter, listenr 加载顺序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    java api最新7.0

    java.beans.beancontext 提供与 bean 上下文有关的类和接口。 java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.lang.annotation 为 Java ...

    Spring bean 加载执行顺序实例解析

    主要介绍了Spring bean 加载执行顺序实例解析,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics