Java面试04|Spring框架
1、动态代理的几种方式
Java主要有两种代理,JDK和Cglib动态代理。先看JDK代理实例如下:
JDK创建代理有一个限制,即它只能为接口创建代理实例。举个例子如下:
public interface Advice {
void beforeMethod();
void afterMethod();
}
public class TimeAdvice implements Advice {
long startTime;
long endTime;
public void beforeMethod() {
startTime = System.nanoTime(); // 获取开始时间
System.out.println("开始计算程序运行时间" + startTime);
}
public void afterMethod() {
endTime = System.nanoTime(); // 获取结束时间
System.out.println("计算程序运行时间: " + (endTime - startTime) + "ns");
}
}
public interface SalaryInterface {
public void doSalary();
}
public class Salary implements SalaryInterface{
public void doSalary() {
System.out.println("进行薪资计算的逻辑处理");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 每一个代理实例都必须指定一个调用处理器,代理对象调用方法时,
* 该方法会指派到调用处理器的invoke()中去。代理的方法封装成
* invoke中的method对象,其中的参数封装成Object[].
*/
public class MyProxy implements InvocationHandler{
private Object obj; // 希望被代理的对象
private Advice advice;
// 绑定代理对象
public Object bind(Object obj, Advice advice) {
this.obj = obj;
this.advice = advice;
return Proxy.newProxyInstance(
obj.getClass().getClassLoader(), // 类加载器
obj.getClass().getInterfaces(), // 创建目标类所需要使用的一组接口
this // 一个实现InvocationHandler的实例,用来整合横切与业务逻辑
);
}
/*
* 实现代理
* method为方法名,args为代理实例某一方法的入参数组,而obj为所属的实例对象
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
advice.beforeMethod();
result = method.invoke(obj, args);
advice.afterMethod();
} catch (Exception e){
e.printStackTrace();
}
return result;
}
}
public class Bootstrap {
public static void main(String[] args) {
Advice advice = new TimeAdvice();
SalaryInterface p = new Salary();
// Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象
MyProxy proxy = new MyProxy();
SalaryInterface y = (SalaryInterface)proxy.bind(p, advice);
y.doSalary(); // 相当于调用proxy.invoke(proxy, "doSalary, null);
}
}
开始计算程序运行时间43041762316001 进行薪资计算的逻辑处理 计算程序运行时间: 882610ns
CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,并顺势织入横切逻辑。
CGGlib创建的代理对象要比JDK的性能高很多,但是创建时所花费的时间却比JDK动态代理要多。所以对于singleton的代理对象或者具有实例池的代码,由于无须频繁创建代码对象,用CGLib比较合适。也就是生命周期长的实例用CGLib比较合适。
/**
* 使用cglib动态代理
*/
public class Cglib implements MethodInterceptor {
private Object target;
long startTime;
long endTime;
/**
* 创建代理对象
*/
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass()); // 设置需要创建子类的类
enhancer.setCallback(this); // 回调方法
return enhancer.create(); // 通过字节码技术动态创建子类实例
}
@Override
// 回调方法 ,拦截所有的父类方法调用
public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
startTime = System.nanoTime(); // 获取开始时间
System.out.println("开始计算程序运行时间" + startTime);
Object result = proxy.invokeSuper(obj, args); // 通过代码类调用父类中的方法
endTime = System.nanoTime(); // 获取结束时间
System.out.println("计算程序运行时间: " + (endTime - startTime) + "ns");
return result;
}
}
/*
* 采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截
* 所有父类方法的调用,并顺势织入横切逻辑
*
* singletom的代理对象或者具有实例池的代理,因为无须频繁创建代理对象,比较适合用CGLib动态代理技术
*
* 由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final,private等方法进行代理
*/
public class TestCglib {
public static void main(String[] args) {
Cglib cglib=new Cglib();
Salary salary=(Salary)cglib.getInstance(new Salary());
salary.doSalary();
}
}
2、Spring AOP(Aspect Oriented Programming面向切面编程)与IoC(Inverse of Control控制反转)的实现
Spring AOP主要就是通过动态代理来实现,而Ioc是通过反射来实现,将创建对象和对象之间的依赖管理交给IoC容器来做,完成对象之间的解耦。
举个反射的例子,如下:
public class Car {
private String brand;
private String color;
private int maxSpeed;
public Car() {
System.out.println("init car!!");
}
public Car(String brand, String color, int maxSpeed) {
this.brand = brand;
this.color = color;
this.maxSpeed = maxSpeed;
}
public void introduce() {
System.out.println("brand:" + brand + ";color:" + color + ";maxSpeed:" + maxSpeed);
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
public class ReflectTest {
public static Car initByDefaultConst() throws Throwable {
// loadClass()方法必须使用全额限定名
ClassLoader loader = Thread.currentThread().getContextClassLoader();
// 每一个类在JVM中都拥有一个对应的java.lang.Class对象,用来描述类结构信息
// Class clazz = loader.loadClass("reflect.Car");
Class clazz = Class.forName("reflect.Car");
Constructor cons = clazz.getDeclaredConstructor((Class[]) null);
Car car = (Car) cons.newInstance();
Method setBrand = clazz.getMethod("setBrand", String.class);
setBrand.invoke(car, "红旗CA72");
Method setColor = clazz.getMethod("setColor", String.class);
setColor.invoke(car, "黑色");
Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
setMaxSpeed.invoke(car, 200);
return car;
}
public static Car initByParamConst() throws Throwable {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("reflect.Car");
Constructor cons = clazz.getDeclaredConstructor(new Class[] { String.class, String.class, int.class });
Car car = (Car) cons.newInstance(new Object[] { "吉利TOPMIX", "绿色", 120 });
return car;
}
public static void main(String[] args) throws Throwable {
Car car1 = initByDefaultConst();
Car car2 = initByParamConst();
car1.introduce();
car2.introduce();
}
}
init car!! brand:红旗CA72;color:黑色;maxSpeed:200 brand:吉利TOPMIX;color:绿色;maxSpeed:120
每一个类在JVM中都拥有一个对应的java.lang.Class对象,它提供了类结构信息的描述。数组、枚举、注解甚至void都有对应的Class对象。可以从Class对象中获取构造函数、成员变量、方法等类元素的反射对象,并以编程的方式通过这些反射对目标类对象进行操作。
3、Spring的事务实现原理
Java面试04|Spring框架的更多相关文章
- Java 横向技术 Spring框架【笔记】
Java横向技术 spring框架[笔记] Spring 的两大特性是什么? AOP(Aspect Oriented Programming,面向切面编程)与 IOC(Inverse of Contr ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第3章.AOP技术
第3章--AOP技术 Spring框架 - AOP概述 笔记https://my.oschina.net/hava/blog/758873Spring框架 - AOP使用 笔记https://my.o ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第2章.IoC容器
第2章.IoC容器 IoC容器概述 abstract: 介绍IoC和bean的用处和使用 IoC容器处于整个Spring框架中比较核心的位置:Core Container: Beans, Core, ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第1章.Spring概述
第1章.Spring概述 Spring概述 The Spring Framework is a lightweight solution and a potential one-stop-shop f ...
- Java开发工程师(Web方向) - 04.Spring框架 - 期末测试
Spring框架客观题 Spring框架编程题 http://blog.csdn.net/sinoacc/article/details/51702458 1 (25分) 假设有如下数据表: crea ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第4章.数据访问
第4章--数据访问 Spring JDBC DAO (Data Access Object) 实现数据访问相关接口(接口和实现分离) ORM (Object Relation Mapping) 对象关 ...
- [Java面试五]Spring总结以及在面试中的一些问题.
1.谈谈你对spring IOC和DI的理解,它们有什么区别? IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建UserService对象的控制权,交由Spri ...
- Java面试之五大框架的理解
五大框架(springMVC,struts2,spring,mybatis,hibernate) 说说你对springMVC框架的理解? 简要口述(如果感觉说的少可以在完整答案里面挑几条说) Spri ...
- 【Java】关于Spring框架的总结 (三)
前文对 Spring IoC 和 Spring AOP 的实现方法进行了整合.如果有不明白的或有质疑的地方可以评论出来,一起探讨问题,帮助别人也是帮助自己!本文探讨的中心主要放在 Spring 的注解 ...
随机推荐
- 【angularjs】【学习心得】路由基础篇
原文:http://www.imooc.com/wenda/detail/236998 AngularJS自带有路由模块ngRoute,但是有经验的老师都推荐我们使用功能更完善更强大的ui-route ...
- redis 实例
打redis模块打开官网 http://www.redis.io/ 进入clients 找到PHP的选项 然后进入phpredis 这就是redis for php的扩展模块 phpize ./co ...
- jdbc数据连接池dbcp要导入的jar包
jdbc数据连接池dbcp要导入的jar包 只用导入commons-dbcp-x.y.z.jarcommons-pool-a.b.jar
- AFN
一.什么是AFN 全称是AFNetworking,是对NSURLConnection的一层封装 虽然运行效率没有ASI高,但是使用比ASI简单 在iOS开发中,使用比较广泛 AFN的github地址 ...
- haproxy学习
1.安装 # wget http://haproxy.1wt.eu/download/1.3/src/haproxy-1.3.20.tar.gz # tar zcvf haproxy-1.3.20.t ...
- java_监控工具jvisualvm
转:使用 VisualVM 进行性能分析及调优 启动:jvisualvm 首先到JDK安装目录/bin目录下,双击jvisualvm.exe文件启动 需要注意的是:当OS所在分区是FAT格式时,Vis ...
- jquery mobile多页面跳转等,data-ajax="false" 问题,
当我们的网站引用了jquery mobile的js后,点击页面的链接,你会发现页面无法跳转,因为jquery mobile默认是采用ajax方式来加载网站的,如果你需要跳到另一个页面,需要在a标签加上 ...
- Struts2系列笔记(4)---Ation类访问servlet
Ation类访问servlet Ation类有三种方式servlet: (1)间接的方式访问Servlet API ---使用ActionContext对象 (2) 实现接口,访问Action时完 ...
- JSP(基础语法)
一.JSP简介 JSP全称为Java Server Pages,其根本是一个简化的Servlet设计,它实现了在java当中使用HTML标签.JSP是一种动态网页技术标准也就是javaEE的标准.JS ...
- Java模拟新浪微博登陆抓取数据
前言: 兄弟们来了来了,最近有人在问如何模拟新浪微博登陆抓取数据,我听后默默地抽了一口老烟,暗暗的对自己说,老汉是时候该你出场了,所以今天有时间就整理整理,浅谈一二. 首先: 要想登陆新浪微博需要 ...