Spring

作者: d24b5d9a8312 | 来源:发表于2019-08-16 22:24 被阅读0次

反射

给定一个类的名字(字符串形式),怎么创建该类的对象?

利用Class类构造实例

什么是反射机制?

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

Java静态代理和动态代理的异同有哪些?
Java类是如何加载的?

java程序的加载过程:源文件 .java --- 经过编译(javac.exe)--- 得到一个或多个 .class文件 --- 再运行(java.exe) --- 就会对需要用到的类进行加载(通过JVM的类加载器)--- 把 .class 加载到内存后 JVM会自动根据.class给java.lang.Class实例化一个Class对象,该对象和.class一一对应(即一个类就一个Class对象)--- 然后再根据 Class对象创建该类的对象。

Java反射机制的定义reflection

获取java类型信息两种方法

1 RTTI run-time type identification更容易读,便于实现
2 反射

Class类

Class类是java一个基础类,每装载个新类的时候,Java虚拟机就会在Java堆中,创建一个Class的实例,这个实例就代表这个Class类型,通过实例获取类型信息。

利用Class类来创建一个实例

newInstance()调用默认构造方法。

Class c=Class.forName("Airplane");
Airplane a=c.newInstance()

Java反射例子Mathod的invoke

反射机制的作用

1.在运行时判断任意一个对象所属的类;
2.在运行时构造任意一个类的对象;
3.在运行时判断任意一个类所具有的成员变量和方法;
4.在运行时调用任意一个对象的方法;
5.生成动态代理。
6.通过反射运行配置文件内容(这就是IOC容器的基本原理)
7.通过反射越过泛型检查

代理模式

在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。

代理模式一般涉及到的角色

抽象角色:声明真实对象和代理对象的共同接口。

代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能够代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

静态代理

//真实对象和代理对象的共同接口
abstract  class Subject {
    public abstract void requet();
}
//真实角色
class RealSubject extends Subject{

    @Override
    public void requet() {
        System.out.println(" From Real Subject!");
    }
}
//代理角色
class ProxySubject extends Subject{
    private RealSubject realSubject;
    @Override
    public void requet() {
        System.out.println("pre request");
        if(null==realSubject){
            realSubject=new RealSubject();
        }
        realSubject.requet();
        System.out.println("post request");
    }
}
//客户端
public class Client{
    public static void main(String[] args) {
        Subject subject=new ProxySubject();
        subject.requet();
    }
}

静态代理的优缺点

优点:

业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。

缺点:

代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。
如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

Java动态代理


动态代理的优点和缺点

优点:动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处
理器一个集中的方法中处理( Invocation Handler invoke)。这样,在接口方法数量比较多的
时候,可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。

缺点: Proxy已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法
摆脱仅支持 interface代理的桎梏。

//抽象角色
public interface Subject {
    public void request();
}
//真实角色
class RealSubject implements  Subject {
    public RealSubject(){};
    @Override
    public void request() {
        System.out.println("From real subject.");
    }
}
//代理角色 必须实现InvocationHandler
public class DynamicSubject implements InvocationHandler {
    private Object sub;
    public DynamicSubject(){};
    public DynamicSubject(Object obj){
        sub=obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before calling"+method);
        method.invoke(sub,args);
        System.out.println("after calling"+method);
        return null;
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
//客户端调用
public class Client {
     public static void main(String args[]){
         RealSubject rs=new RealSubject();//在这里指被代理类
         InvocationHandler ds=new DynamicSubject(rs);
         Class cls=rs.getClass();
         Subject subject=(Subject) Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),ds);
         subject.request();
     }
}

类加载

JVM类加载器种类

JVM自带的默认加载器

1.根类加载器: bootstrap,由C++编写,所有Java程序无法获得。
2.扩展类加载器:由ava编写。
3.系统类、应用类加载器:由Java编写。

用户自定义的类加载器

Java. lang ClassLoader的子类,用户可以定制类的加载方式。每一个类都包含了加载他的 ClassLoader的一个引用——getClassLoader()如果返回的是null,证明加载他的 ClassLoader.是根加载器 bootstrap。

类的加载方式

本地编译好的class中直接加载
网络加载:java.net.URLClassLoader可以加载url指定的类
从jar、zip等等压缩文件加载类,自动解析jar文件找到class文件去加载
从java源代码动态编译成class文件

类加载步骤

加载
连接

验证 准备(默认初始值) 解析

类的初始化

ClassLoader加载顺序

根加载器 拓展类加载器 应用类加载器 用户自定义类加载器
最后都加载不了 ClassNotFoundException

ClassLoader加载Class过程

注解

什么是注解

注解也叫元数据,例如我们常见的@Override和@Deprecated,注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。

注解的主要用途

生成文档,通过代码里标识的元数据生成javadoc文档。

编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。

编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。

运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。

Spring

IoC:控制反转,控制权的转移,应用程序本身不负责依赖对象的创建和维护,而是由外部容器负责创建和维护,获得依赖的过程的控制被翻转。

DI(依赖注入)是其一种实现方式。
目的:创建对象并且组装对象之间的关系

Bean的作用域scope

singleton:单例,指一个Bean容器中只存在一份
Protottype:每次请求(每次使用)创建新的实例, destroy方式不生效

初始化bean销毁bean

Bean的自动装配

No:不做任何操作
byname:根据属性名自动装配。此选项将检查容器并根据名字
查找与属性完全一致的bean,并将其与属性自动装配
先用没有参数的构造器得到对象,再根据set方法寻找id与set()一样的bean

byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型bean,那么抛出异常,并指出不能使用 by Type方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生

Constructor与 byType方式类似,不同之处在于它应用于构
造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常

针对于资源文件的统一接口Resources

UrIResource:URL对应的资源,根据一个∪RL地址即可构建
ClassPath Resource:获取类路径下的资源文件
File SystemResource:获取文件系统里面的资源
ServletContextResource: Servletcontext封装的资源,用于访问 ServletContext环境下的资源
InputStreamResource:针对于输入流封装的资源
ByteArray Resource:针对于字节数组封装的资源

从 Spring3.0开始, Spring Java Config项目提供了很多特性,包括使用java而不是XML定义bean,比如

@Configuration, @Bean, @Import, @ DependsOn
@ Component是一个通用注解,可用于任何bean
@ Repository,@ Service,@ Controller是更有针对性的注解
@ Repository通常用于注解DAO类,即持久层
@ Service通常用于注解 Service类,即服务层
@ Controller通常用于 Controller类,即控制层(MVc)

Spring可以自动检测类并注册Bean到 Application Context中扫描过程中组件被自动检测,那么Bean名称是由
Bean Name Generator生成的(@ Component
@ Repository,@ Service,@ Controlller都会有个name属性用于显式设置 Bean Name)

@ Required注解适用于bean属性的 setter方法
这个注解仅仅表示,受影响的bean属性必须在配置时被填充
通过在bean定义或通过自动装配一个明确的属性值

@Autowired
可将@Autowired注解为传统的setter方法
用于构造器或成员变量
每个类只能有一个构造器require为true

可以通过添加注解给需要该类型的数组的字段或方法,以提供
Application Contextl中的所有特定类型的bean

可以用于装配key为string的map

@Qualifier
按类型自动装配可能多个bean实例的情况,可以使用 Spring
的@ Qualifier注解缩小范围(或指定唯一),也可以用于指定
单独的构造器参数或方法参数
可用于注解集合类型变量

因语义差异,集合或Map类型的bean无法通过@ Autowired
来注入,因为没有类型匹配到这样的bean,为这些bean使用
@ Resource注解,通过唯一名称引用集合或Map的bean

@ Autowired适用于 fields, constructors, multi- argument
methods这些允许在参数级别使用@ Qualifier注解缩小范围
的情况
@ Resource适用于成员变量、只有一个参数的 setter方法,所
以在目标是构造器或一个多参数方法时,最好的方式是使用
Qualifiers

@Bean和@Configuration可以达到和xml一样的配置效果

如果希望数组有序,可以让bean实现
org. springframework core. Ordered口或使用的
@ Order注解

AoP: Aspect Oriented Programming的缩写,意为:面
向切面编程,通过预编译方式和运行期动态代理实现程序功能
的统一维护的一种技术
主要的功能是:日志记录,性能统计,安全控制,事务处理
异常处理等等

预编译
Aspect
运行期动态代理(JDK动态代理、 CGLib动态代理)
SpringAOP、 JbossAOP

AOP几个相关概念
名称
说明

切面( Aspect)

个关注点的模块化,这个关注点可能会横切多个对象

连接点( Joinpoint)

程序执行过程中的某个特定的点

通知( Advice)

在切面的某个特定的连接点上执行的动作
切入点( Pointcut)
匹配连接点的断言,在AOP中通知和一个切入点表达式关联

引入( Introduction)

在不修改类代码的前提下,为类添加新的方法和属性

目标对象( Target Object)

被一个或者多个切面所通知的对象

AOP代理( AOP Proxy)

AOP框架刨建的对象,用来实现

切面契约( aspect

contract)(包括通知方法执行等功能)

织入( Weaving)

把切面连接到其它的应用程序类型或者对象上,并刨建一个被通知的对象,分为:编译时织入、类加载时织入、执行时织入

前置通知( Before advice)

在某连接点( join point)之前执行的通
知,但不能阻止连接点前的执行(除非它
抛出一个异常)

返回后通知( After returning advice)

在某连接点( join point)正常完成后执行的通知

抛出异常后通知( After throwing

在方法抛出异常退出时执行的通知
advice)

后通知( After( finally) advice)

当某连接点退出的时候执行的通知(不论
是正常返回还是异常退出)

环绕通知( Around Advice)

包围一个连接点( join point)的通知

Spring的AOP实现

纯java实现,无需特殊的编译过程,不需要控制类加载器层次目前只支持方法执行连接点(通知 Spring Bean的方法执行)
不是为了提供最完整的AOP实现(尽管它非常强大):而是侧重于提供一种AOP实现和 Spring loc容器之间的整合,用于帮助解决企业应用中的常见问题
Spring AOP不会与 Aspect竟争,从而提供综合全面的AoP
解决方案

相关文章

网友评论

      本文标题:Spring

      本文链接:https://www.haomeiwen.com/subject/ahhcsctx.html