反射器、IOC/DI,动态代理、AOP

本文介绍了Java反射机制的概念、作用及优缺点,重点讲解了反射的入口Class类。接着讨论了IOC/DI,解释了控制反转和依赖注入的概念,并阐述了Spring框架中的应用。此外,文章还深入探讨了动态代理,包括其优点和在Spring AOP中的应用。最后,简单介绍了AOP的原理和Spring AOP的底层实现,包括JDK动态代理和CGLib。

反射的概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

反射的作用

类的加载器可以获得类中的东西:属性,构造方法,功能方法。即

动态创建对象

动态操作属性

动态调用方法

反射的优点
灵活、自由度高:不受类的访问权限限制,想对类做啥就做啥;

反射的缺点
性能问题:通过反射访问、修改类的属性和方法时会远慢于直接操作,但性能问题的严重程度取决于在程序中是如何使用反射的。如果使用得很少,不是很频繁,性能将不会是什么问题;

安全性问题:反射可以随意访问和修改类的所有状态和行为,破坏了类的封装性,如果不熟悉被反射类的实现原理,随意修改可能导致潜在的逻辑问题;

兼容性问题:因为反射会涉及到直接访问类的方法名和实例名,不同版本的API如果有变动,反射时找不到对应的属性和方法时会报异常;

反射的入口——class类

 

IOC/DI
IOC(控制反转):以前依赖的对象自己直接new,现在不需要new,框架会自动注入,创建对象的权利转移给了框架

DI(依赖注入):一个类的功能需要依赖另一个类的配合,同时需要赋上一个具体的对象,则这种关系是依赖注入

Spring框架负责所有对象的创建、管理和依赖注入,所有对象储存的容器叫做IOC容器

核心配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

dao层:

package com.zhang.dao;
 
public interface BookDao {
 
    public void study();
 
}
 
 
 
 
 
package com.zhang.dao.impl;
 
import com.zhang.dao.BookDao;
 
public class BookDaoImpl implements BookDao {
    @Override
    public void study() {
 
    }
}

service层

package com.zhang.service.impl;
 
import com.zhang.dao.BookDao;
import com.zhang.service.BookService;
 
public class BookServiceImpl implements BookService {
 
    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("BookServiceImpl---------save");
        bookDao.study();
    }
}
 
 
 
 
package com.zhang.service;
 
public interface BookService {
    void save();
}

servlet层:

package com.zhang.servlet;
 
import com.zhang.service.BookService;
import com.zhang.service.impl.BookServiceImpl;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class BookServlet {
 
    BookService bookService;
 
    @Test
    public void add(){
        System.out.println("bookService---------");
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("Spring.xml");
        bookService= (BookService) context.getBean("bookService");
        bookService.save();
    }
}

动态代理
动态代理是一种常用的设计模式,广泛应用于框架中,Spring框架的AOP特性就是应用动态代理实现的,想要理解AOP的实现原理我们就必须先理解动态代理。

什么是代理模式
代理模式是GOF23设计模式之一,代理模式中存在代理者和被代理者,代理者和被代理者都具有相同的功能,并且代理者执行功能时会附加一些额外的操作

代理模式的优点
符合开闭原则,不用修改被代理者任何的代码,就能扩展新的功能
项目的扩展和维护比较方便 

    public static void main(String[] args) {
        //明确要代理的对象
        Actor cxk=new CXK();
        /**
         * 创建代理对象,具体某个人作为经纪人,对代理对象的方法进行服务(功能增强)
         * 参数1,ClassLoader loader  被代理的类的类加载器(底层使用的反射)
         *     2,Class<?>[] interfaces   被代理的类的接口类型(类型的判断)
         *     3,InvocationHandler h   被代理后要做什么事情
         */
        Actor jjr= (Actor) Proxy.newProxyInstance(CXK.class.getClassLoader(), CXK.class.getInterfaces(), new InvocationHandler() {
            /**
             * Object proxy:被代理对象的一个引用
             * Method method:被代理对象的方法
             * Object[] args:方法被执行时需要的参数列表
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 
                //前置增强
                System.out.println("进行巡演造势");
                //方法的三要素
                Object result=null;
                String methodName= method.getName();
                System.out.println(methodName);
 
                //方法执行需要一个对象的引用
                result=method.invoke(cxk,args);
 
                //后置增强
                System.out.println("结算和纳税");
 
                return result;
            }
        });
 
        //3,执行方法,由代理对象进行执行
        jjr.sing(5,3.14);
 
        jjr.rap();
    }
}

AOP

AOP全名Aspect-oriented programming面向切面编程大法,它有很多兄弟,分别是经常见的面向对象编程,朴素的面向过程编程和神秘的函数式编程等。AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理

AOP是什么原理?
AOP代表的是一个横向的关系,相比于纵向的继承关系更加简便。将“对象”比作一个空心的圆柱体,其中封装的是对象的属性和行为;则面向方面编程的方法,就是将这个圆柱体以切面形式剖开,可以选择性的提供业务逻辑。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹,但完成了效果。

Spring AOP 底层实现
 JDK 动态代理:基于接口实现
CGLib 是基于类的继承实现的

首先导入IOC和AOP所需要的jar包

 

 创建UserService类,这个类完成核心功能操作。

void findAll();
    void save(int a);
    int del();
    void update();
/**
 * 核心类
 */
public class BookServiceImpl implements BookService {
    @Override
    public void findAll() {
        System.out.println("查询所有");
    }
 
    @Override
    public void save(int a) {
        System.out.println("保存信息"+a);
    }
 
    @Override
    public int del() {
        System.out.println("删除信息");
        return 5;
    }
 
    @Override
    public void update() {
        System.out.println("修改信息");
    }
}

创建Logger类,这个类是用来做功能的增强。

   /**
     * 增强类
     */
 
    public void check() {
        System.out.println("前置通知/增强:权限验证");
    }
 
    public void logprint(){
        System.out.println("后置通知/增强:日志输出");
    }
 
    public void exception(){
        System.out.println("异常通知/增强:异常处理");
    }
 
    public void distory(){
        System.out.println("最终通知/增强:资源释放");
    }
}

在spring的beans.xml中开始进行AOP的配置:
首先把核心类和增强类的bean配置到IOC的容器中使用<aop:config>标签在进行AOP的配置,先通过aop:aspect标签标明谁是增强类。然后在标签中进行aop:before(前置)、aop:after-returning(后置)、aop:after-throwing(异常)、aop:after(最终)的配置,让增强类的某个方法对核心功能类的某一类方法进行功能增强。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
 
    <!--1.把所有类的对象交给IOC容器进行管理-->
    <bean id="logger" class="com.gao.logger.Logger"/>
    <bean id="bookService" class="com.gao.service.impl.BookServiceImpl"/>
    <!--2.AOP的配置:让增强类 的 哪个方法  动态进行何种增强   核心类 的 哪个方法-->
    <aop:config>
        <!--指定增强类并起个名字-->
        <aop:aspect id="check" ref="logger">
        <!--前置通知/增强:在核心类方法执行之前  进行  增强-->
            <aop:before method="check" pointcut="execution(* *..BookServiceImpl.*(..))"/>
            <aop:before method="logprint" pointcut="execution(* *..BookServiceImpl.*(..))"/>
            <aop:before method="exception" pointcut="execution(* *..BookServiceImpl.*(..))"/>
            <aop:before method="distory" pointcut="execution(* *..BookServiceImpl.*(..))"/>
        </aop:aspect>
    </aop:config>
 
</beans>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值