浅谈IOC、AOP、反射实现AOP代理

本文深入探讨了Spring框架的核心概念——IOC(控制反转)和AOP(面向切面编程)。详细介绍了IOC的创建方式,包括set注入、构造注入和p空间注入等,并讲解了AOP的基本原理和创建过程,包括注解和XML配置实现。此外,还讨论了通过反射实现AOP代理的方法,结合实例展示了其实现步骤。

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

目录

1.IOC控制反转

创建方式

2.AOP面向切面

①创建方式

注解

五种增强 

反射实现AOP代理


Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

1.IOC控制反转

控制反转(inversion of control), 是一种设计思想,DI(dependency injection依赖注入)是IOC的一种方法

控制反转就是将对象的创建转移给了第三方。

创建方式

  • 创建一个applicationContext.xml核心配置文件,功能全部写入此文件中
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
  • set注入
    <!--依赖注入  set注入  name变量名,value输入的值-->
   <!--name的值跟类中对应-->
    <bean id="cat" class="entity.Cat">
        <property name="cid" value="1"></property>
        <property name="cname" value="煤炭"></property>
    </bean>
  • 构造注入
  <!--构造注入 实体类需要创建构造器--> 
<bean id="cat" class="entity.Cat">
        <constructor-arg name="cid" value="1"></constructor-arg>
        <constructor-arg name="cname" value="多多"></constructor-arg>
 </bean>
  • p空间注入

    <!--p空间注入 头部先要申明p空间      xmlns:p="http://www.springframework.org/schema/p"-->
    <bean id="cat" class="entity.Cat" p:cid="2" p:cname="七月"> </bean>

  •  对象注入
<bean id="dog" class="entity.Dog">
<property name="did" value="1"></property><!--依赖注入-->
    <property name="dname" value="小白"></property>


   <bean id="cat" class="entity.Cat">
        <property name="cid" value="1"></property>
        <property name="cname" value="煤炭"></property>
     
    </bean>


    <bean id="master" class="entity.Master">
   <!--name的值跟类中对应-->
        <property name="c" ref="cat"></property><!--依赖注入-->
        <property name="d" ref="dog"></property>
    </bean>

  • 测试页面

public class Test {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        //通过工厂的指定流水线 来生产
          Dog d= (Dog)ac.getBean("dog");//ioc
        Cat c=(Cat) ac.getBean("cat");
        System.out.println(d.getDid()+"~~"+d.getDname());
        System.out.println("---------------------------------");
        Master m= (Master) ac.getBean("master");
        System.out.println(m.getC().getCname()+"~~"+m.getD().getDname());

    }
}

2.AOP面向切面

AOP为Aspect Oriented Programming,面向切面编程,通过预编译方 式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是OOP的延续

①创建方式

  • 创建一个原始类,里面写入方法

  • 创建aop,里面写入要插入的方法

  • 导入aop
 <bean id="aop" class="aop.MyAop"></bean>
  •  xml文件实现代码
  <aop:config>
        <!--找到切点,就是要插入内容的地方-->
        <aop:pointcut id="pc" expression="execution(public int study())"/>
        <!--通过切点 打开切面 引入新的需求-->
        <aop:aspect ref="aop">
            <!--前置增强,就是在方法前插入新方法-->
            <!--method要插入的方法名  pointcut-ref插入的地点-->
            <aop:before method="WashFace" pointcut-ref="pc"></aop:before>
            <!--后置增强,就是在方法后插入新方法-->
            <aop:after-returning method="eat" pointcut-ref="pc" returning="result"></aop:after-returning>
 <!--最终增强-->
            <aop:after method="myFinal" pointcut-ref="pc"></aop:after>
            <!--环绕增强-->
            <aop:around method="around" pointcut-ref="pc"></aop:around>
            <!--异常增强  需要在方法里抛出一个异常-->
            <aop:after-throwing method="error" pointcut-ref="pc" throwing="e"></aop:after-throwing>
        </aop:aspect>
    </aop:config>

  •  测试页面

public class Test {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student stu= (Student) ac.getBean("stu");
        stu.study();
    }
}
  • 结果

注解

  • xml配置文件
<context:component-scan base-package="entity,aop"></context:component-scan>
    <!--支持AOP注解-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 实体类
package entity;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//@Component相当于把这个类  加载成ben标签
@Component
public class Tiger {
    //Value赋值
    @Value("111")
    private int id;
    @Value("万分v")
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package entity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Master {
    //  @Resource根据类型匹配    @Resource根据名字匹配,jdk自带
    @Autowired
    private Tiger t;
    @Autowired
    private Pig p;

    public Tiger getT() {
        return t;
    }

    public void setT(Tiger t) {
        this.t = t;
    }

    public Pig getP() {
        return p;
    }

    public void setP(Pig p) {
        this.p = p;
    }
}

  • 测试类
package test;

import entity.Chef;
import entity.Master;
import entity.Pig;
import entity.Tiger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import reflect.Student;

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

public class Test {
    public static void main(String[] args)throws Exception {
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        //注解getBean默认生成改类的名小写名称
        Tiger t= (Tiger) ac.getBean("tiger");
        System.out.println(t.getId()+"~~"+t.getName());
        Master m= (Master) ac.getBean("master");
        System.out.println(m.getP()+"~~"+m.getT());

        Chef ch= (Chef) ac.getBean("chef");
        System.out.println(ch.getName()+"用"+ch.getM().getName()+"和"+ch.getV().getName()+"做出了辣椒炒肉");

        Pig p= (Pig) ac.getBean("pig");
        p.eat();
  • 结果
  •   
  • 五种增强 

  • 实体类
package reflect;

public class Student {
    private int sid;

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String name;
    public void play(){
        System.out.println("学习");
    }
}

  • aop类 
package aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect//注解为切面
public class MyAop {
    //前置增强
    @Before("pc()")
    public void before(){
        System.out.println("吃饭之前要洗手");
    }
    //找到切点
    @Pointcut("execution(public void eat())")
    public void pc(){
    }

    @AfterReturning("pc()")
    public void afterreturing(){
        System.out.println("我是后置增强");
    }


    @After("pc()")
    public void After(){
        System.out.println("我是最终");
    }


    @Around("pc()")
    public void Around(ProceedingJoinPoint pjp){
        System.out.println("我是前面的环绕");
        try {
            pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("我是后面的环绕");
    }

    @AfterThrowing(value = "pc()",throwing = "e")
    public  void error(Exception e){
        System.out.println("我是异常增强");
    }
}
  • 结果 

反射实现AOP代理

  • 实体类
package reflect;

public class Student {
    private int sid;

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String name;
    public void play(){
        System.out.println("学习");
    }
}
  •  测试类

        //反射   三种方式
        //第一种通过实例方法
        Class<Student> c= Student.class;
        //第二种forName
        Class<Student> c1= (Class<Student>) Class.forName("reflect.Student");
        //第三种getClass
        Class<Student> c2= (Class<Student>) new Student().getClass();

        //直接获取类中所有属性
        Field[] fields=c.getDeclaredFields();
        Student s = null;
        try {
            s=c.newInstance();

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        
        for (Field f:fields) {
            if(f.getName().equals("sid")){
                f.setAccessible(true);//可直接更改属性(私有属性也可)的访问权限  临时
                f.set(s,123);
            }
            System.out.println(f.getName());
        }
        //----------------------------
        //获取方法
        Method[] methods=c.getMethods();
        for (Method me:methods) {
            System.out.println(me.getName());
        }
        //----------------------------
        //获取构造方法
        Constructor[] constructors=c.getConstructors();
        for (Constructor ct:constructors) {
            System.out.println(ct.getName());
        }
        //----------------------------
        //输出上面sid临时赋的值
        System.out.println(s.getSid());
    }

  • 结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值