Spring

目录

一、Spring的组件与核心

1.Bean、Context、Core三大核心组件的关系:

2.Spring框架两大核心:IoC和DI

二、Spring的IOC 

1.概述

2.注解方式实现IOC

三、模拟IOC的实现

1.创建Bean类,描述类的信息

2.创建Spring容器,并指定要维护的类,提供getBean(),根据beanName获取对象

3.创建类

4.测试

 四、DI

1.概述

2.测试SpringDI

 3.DI的自动装配

五、AOP面向切面编程

1.概念

2.Spring  AOP有三要素

3.通知的执行顺序

4.多切面执行顺序

 5.测试


一、Spring的组件与核心

1.Bean、Context、Core三大核心组件的关系:

Bean 包装的是 Object,而 Object 必然有数据,如何给这些数据提供生存环境就是 Context要解决的问题,对 Context 来说它就是要发现每个 Bean 之间的关系,为它们建立这种关系并且要维护好这种关系。所以 Context 就是一个Bean关系的集合,这个关系集合又叫 Ioc 容器,一旦建立起这个 Ioc 容器后 Spring 就可以为你工作了。那 Core 组件又有什么用武之地呢?其实Core 就是发现、建立和维护每个 Bean 之间的关系所需要的一些类的工具,从这个角度看来,Core 这个组件叫 Util 更能让你理解。

2.Spring框架两大核心:IoC和DI

概念
IoC(Inversion of Control)简单来说就是将对象Object的创建的权力及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不在需要关注对象的创建和生命周期的管理,而是在需要的时候由Spring框架提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转。
在创建对象的过程中Spring可以依据对象的关系,自动把其它对象注入(无需创建对象,直接拿着使用)进来,这个过程称之为DI(Dependency Injection)依赖注入。
总结下Spring核心就干了两件事:

1.创建对象
2.设置对象的关联关系

二、Spring的IOC 

1.概述

Inversion of Control,控制反转,是指把管理对象的权利交给spring框架。

2.注解方式实现IOC

哪个类想让spring框架new,就在类上使用注解:@Component / @Service / @Controller

(1)创建类,使用注解

#Map<类名首字母要小写,类的对象> - {user=new User()}
@Component
public class User {
    public void get(){
        System.out.println("hello springioc");
    }
}

(2)创建配置文件,只需要指定包的路径

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 包扫描:只需要指定从哪个包开始扫描,
        用了@Component注解的类,自动ioc
        base-package需要指定一个包的路径
    -->
    <context:component-scan base-package="cn.tedu.spring2"></context:component-scan>

</beans>

 (3)读取配置文件,获取对象

package cn.tedu.test;

import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//测试 注解开发
public class TestIOC2 {
    @Test
    public void ioc2(){
        //1,读取核心配置文件
        ClassPathXmlApplicationContext spring =
                new ClassPathXmlApplicationContext(
                        "spring-config2.xml");
        //2,getBean -- 参数是类名,但是首字母要变成小写才行
        Object o = spring.getBean("user");
        System.out.println(o);//cn.tedu.spring2.User@37d4349f

        Object o2 = spring.getBean("userInfo");
        System.out.println(o2);//cn.tedu.spring2.UserInfo@2805d709

    }
}

三、模拟IOC的实现

1.创建Bean类,描述类的信息

//描述一个类的信息,spring把每个类当做一个bean
@Data
@AllArgsConstructor 
public class Bean {
    private String beanName;//类的名字
    private String beanPath;//类的全路径 
}

2.创建Spring容器,并指定要维护的类,提供getBean(),根据beanName获取对象

public class MyIOC {
    //1,创建list,存好多bean
    private List<Bean> beans = new ArrayList<>();
    public MyIOC() throws Exception {
        Bean b1 = new Bean("hello","cn.tedu.myioc.Hello");
        Bean b2 = new Bean("user","cn.tedu.myioc.User");
        beans.add(b1);
        beans.add(b2);
        //new
        init();
    }
    Map<String,Object> map = new HashMap<>();
    //2,创建map,存对象 { hello=new Hello() , user=new User()}
    public void init() throws Exception {
        //遍历list,获取每个bean
        for(Bean b : beans){
            String key = b.getBeanName();
            String quanlujing = b.getBeanPath();
            Object value = Class.forName(quanlujing).newInstance();
            map.put(key,value);
        }
    }
    //3,getBean()--根据key获取value
    public Object getBean(String beanname){
        return map.get(beanname) ;
    }
}

3.创建类

4.测试

public class Test1 {
    public static void main(String[] args) throws Exception {
        MyIOC my = new MyIOC();

        //根据类名,获取类的对象
        Object o = my.getBean("hello");
        System.out.println(o);//cn.tedu.myioc.Hello@54bedef2

        //根据类名,获取类的对象
        Object o2 = my.getBean("user");
        System.out.println(o2);//cn.tedu.myioc.User@5caf905d
    }
}

 四、DI

1.概述

依赖注入,前提是先使用注解@Component完成IOC                                                                        两个类(对象)间的关系,使用@Autowried完成DI     

2.测试SpringDI

(1)创建Teacher类

@Component//ioc
public class Teacher {
    public String name = "jack" ;
    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + '\'' +
                '}';
    }
}

 (2)创建Student类

@Component//ioc
public class Student {
    public String name = "蔡徐坤" ;
    // 表示两个类之间的关系
    @Autowired//DI依赖注入,自动装配,自动布线
    Teacher t ;
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", t=" + t +
                '}';
    }
}

(3) 创建核心配置文件,配置包扫描的路径

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--包扫描:扫描指定包路径下的所有类
        哪些类有@Component注解,就帮哪些类new-ioc
    -->
    <context:component-scan base-package="cn.tedu.vo"></context:component-scan>
</beans>

(4)测试

//测试springdi
public class Test2 {
    public static void main(String[] args) {
        //1,读取核心配置文件
        ClassPathXmlApplicationContext spring =
                new ClassPathXmlApplicationContext(
                        "spring-config.xml");
        //2,根据类名,获取对象
        //右侧返回的是Object父类,左侧要子类--需要强转--向下转型--是为了使用子类的功能
        Teacher t = (Teacher) spring.getBean("teacher");
        System.out.println(t);//Teacher{name='jack'}

        Student s = (Student) spring.getBean("student");
        //DI:在获取学生信息的同时,也获取到了关联的老师信息
        System.out.println(s);//Student{name='蔡徐坤', t=Teacher{name='jack'}}
    }
}

 3.DI的自动装配

利用注解方式,我们只需要写@Autowired注解,底层就会去容器中找对应的对象,如果有获取到,反射调用其对应的set方法,设置。而这个调用过程都是自动,我们没有手工去写set方法。所以这个过程也称为自动装配。

五、AOP面向切面编程

1.概念

Spring核心特征中除了IoC控制反转、DI依赖注入,还有一个核心就是强大的面向切面编程AOP(Aspect Oriented Programming)的实现。

2.Spring  AOP有三要素

(1)Aspect定义切面;
(2)通过通知(Advice)来指定具体做什么事情。如方法执行前做什么,方法执行后做什么,抛           出异常做什么,从而实现对象行为(方法)的增强;
(3)具体通过切点(PointCut)配置切点表达式(expression)来指定在哪些类的哪些方法上织            入(ware)横切逻辑;被切的地方叫连接点(JoinPoint);
 

3.通知的执行顺序

Spring框架实现了AOP面向切面,其引入了第三方AspectJ框架来具体实现。AspectJ提供了五种切入方式,术语称为通知advice。

具体五种为:

(1)前置通知before
(2)后置通知after
(3)环绕通知around
(4)返回后通知afterReturning
(5)异常通知afterThrowing。
可以看到,分别在业务方法(Business Method)的执行前后进行拦截,执行指定的代码。

4.多切面执行顺序

 下面是 两个切面 各通知的执行顺序:

 5.测试

(1)需求:

 (2)添加依赖

   <dependencies>
        <!--添加aop依赖包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
    </dependencies>

(3)测试

@Component
@Aspect       切面:由切点和通知组成
public class AspectTest {
    //切点表达式: *表示1个 ..表示多个 *依次代表方法返回值,类名,方法名,(..)是参数列表
    @Pointcut("execution( * cn.tedu.service..*.*(..))")
    public void pointcut(){}

    //添加环绕通知,在业务方法执行前后添加功能
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object o = joinPoint.proceed();//执行业务方法并返回结果
        long end = System.currentTimeMillis();

        String methodname = joinPoint.getTarget().getClass().getName()//获取类名
                +"."+joinPoint.getSignature().getName();//获取方法名

        System.out.println("根据aop统计,"+methodname+"方法的耗时是:"+(end-start));
        return o;//执行完方法的返回值
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值