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

本文介绍了Java反射机制,包括反射的概念、常用类和作用,详细讲解了反射的入口Class类。接着讨论了Spring框架中的IOC/DI思想,解释了控制反转和依赖注入的概念。进一步探讨了动态代理和代理模式,阐述了其优点。最后,深入剖析了AOP,包括AOP的原理和Spring AOP的底层实现,以及五种不同类型的通知形式。通过示例代码展示了如何在Spring中配置AOP。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反射

1.什么是反射

1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。
2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

2.常用的类文件

3.反射的作用

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

  • 动态创建对象
  • 动态操作属性
  • 动态调用方法

4.反射的入口——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.gao.dao;
 
public interface BookDao {
 
    public void study();
 
}
 
 
 
 
 
package com.gao.dao.impl;
 
import com.gao.dao.BookDao;
 
public class BookDaoImpl implements BookDao {
    @Override
    public void study() {
 
    }
}

service层

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

servlet层:

package com.gao.servlet;
 
import com.gao.service.BookService;
import com.gao.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设计模式之一,代理模式中存在代理者和被代理者,代理者和被代理者都具有相同的功能,并且代理者执行功能时会附加一些额外的操作

如:手机工厂和代理商都具有卖东西的功能,手机代理商除了帮工厂卖手机外,还能在卖手机前打广告推销,卖手机后还可以进行售后服务

代理模式的优点

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

示例代码

    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?

利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
简单来说:使用AOP可以在不修改源码的基础上,增加新的功能。(显而易见,这对于大型项目开发来说是极具诱惑的。减少了版本更迭时的工作量)

AOP是什么原理?

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

Spring AOP 底层实现

  •  JDK 动态代理:基于接口实现
  • CGLib 是基于类的继承实现的

五种通知形式

Before advice :前置通知,目标方法前执行,无论目标方法是否遇到异常都执行
After returning advice:后置通知,目标方法执行后执行,前提是目标方法没有遇到异常,遇到异常则不执行
After throwing advice:异常通知,顾名思义,在目标方法抛出异常时执行
After finally advice:最终通知,在目标方法执行后执行,无视是否异常
Around advice:环绕通知:最强大的通知类型,可以控制目标方法的执行(通过调用ProceedingJoinPoint.proceed() 执行目标方法),可以在目标执行全过程中执行。

 实现

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

2. 创建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、付费专栏及课程。

余额充值