Spring的详细介绍与配置

Spring的核心思想:对象容器 把对象放在容器中供调用者使用

Spring的核心功能:控制反转(IOC)和面向切面编程(AOP)

Spring是对对象的管理,目的是为了解除代码之间的耦合

Spring是框架的粘合剂,它可以整合其他框架

1.spring的体系

 

       Spring 由 20 多个模块组成,它们可以分为数据访问/集成(Data Access/Integration)、 Web、面向切面编程(AOP, Aspects)、提供JVM的代理(Instrumentation)、消息发送(Messaging)、 核心容器(Core Container)和测试(Test)

2.Spring的核心功能:IOC

IOC:控制反转,以前我们主动创建对象,对象创建的权利由我们自己掌控,这种方式会导致我们代码之间耦合度过高。我们把创建对象的权利交给spring容器,由spring容器创建对象,我们从容器中拿对象,对象创建的权利交给类别人,这叫控制反转

控制反转的作用:解除代码间的耦合

2.1、spring的容器环境

依赖管理

<!--使用spring的环境 去管理对象-->
<!--搭建spring的bean容器环境-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.3.20</version>
</dependency>

Spring的容器环境:

Spring的配置文件

<?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">
    <!--xml有两种约束  dtd  xsd-->
    <!--xmlns:命名空间
        xsi:schemaLocation:约束文件地址
    -->
    <!--这就是spring读取要被容器管理对象的配置信息-->
    <!--id:该对象在spring容器中的唯一标识
        class:类的全限定名  spring会反射得到该类的对象
    -->
    <bean id="u" class="com.powernode.bean.User"/>
</beans>

测试:

@Test
public void  testGetUser(){
    //不在主动创建对象  从spring容器中得到对象
    //1、 获取spring容器
    ClassPathXmlApplicationContext beans =  new ClassPathXmlApplicationContext("spring.xml");
    Object obj = beans.getBean("u");
    User user = (User)obj;
    user.setUname("张三");
    System.out.println("user = " + user);
}

2.2、Spring读取配置对象的方式

<!--默认调用无参构造创建对象-->
<!--<bean id="u" class="com.powernode.bean.User"/>-->
<!--2、配置指定有参构造函数-->
<bean id="u1" class="com.powernode.bean.User">
    <constructor-arg name="uid" value="1001"/>
    <constructor-arg name="uname" value="李四"/>
    <constructor-arg name="ucode" value="888123"/>
    <constructor-arg name="upwd" value=""/>
</bean>
<!--3、使用无参构造和set方法-->
<bean id="u2" class="com.powernode.bean.User">
    <property name="uname" value="张三"/>
    <property name="upwd" value="123"/>
</bean>

2.3、IOC的衍生技术:DI

DI:依赖注入  当A对象依赖B对象时  A对象叫依赖对象 B对象叫被依赖对象

把B对象当做属性放在A对象中  提供set方式  让spring容器管理AB对象 并把B对象通过set方法注入给A对象

依赖注入的前提:依赖类和被依赖类都被spring容器管理

//被依赖类
public class UserDao {
    public void addUser(){
        System.out.println("这是UserDao中的添加方法");
    }
}

//UserService需要UserDao的支持   依赖UserDao
//UserService也是一个类  可以让spring容器帮忙
//依赖类
public class UserService {
    private  UserDao userDao;
    public void savUserService(){
        /*UserDao userDao = new UserDao();//耦合度过高*/

        userDao.addUser();
    }


    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

依赖注入的配置

<!--依赖注入-->
<!--被依赖类-->
<bean id="ud" class="com.powernode.dao.UserDao"/>
<!--依赖类-->
<!--ref:引入spring容器手里对象的地址值-->
<bean id="us" class="com.powernode.service.UserService">
    <property name="userDao" ref="ud"/>
</bean>

测试:

@Test
public void testGetUs(){
    ClassPathXmlApplicationContext beans =  new ClassPathXmlApplicationContext("spring.xml");
    UserService userService =(UserService)beans.getBean("us");
    userService.savUserService();
}

2.4、Spring的注解方案

注解是为了简化配置文件的书写

Spring在IOC中提供了两类注解:

  1. 实体类注解  在实体类上加上注解  让spring容器扫描即可

每个bean注解都有value属性 不写默认是类名的小驼峰式

@Component:普通实体类注解

@Controller:当前类为处理器类

@Service:当前类为业务层

@Repository:当前类为持久层

注意:注解方案使用的是无参构造  保证类有无参函数

@Component("user")//在spring容器中  它的唯一标识是u
public class User {
    private int uid;
    private String uname;
    private String ucode;
    private String upwd;

<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">
    <!--使用注解来加载对象-->
    <!--<context:component-scan base-package="com"/>-->
    <!--注解扫描器的配置  开发中不建议写大范围扫描-->
    <!--<context:component-scan base-package="com.powernode1.bean"/>
    <context:component-scan base-package="com.powernode1.dao"/>
    <context:component-scan base-package="com.powernode1.service"/>-->
    <!--使用分隔符号 ,或;  在一个扫描器中配置多个包-->
    <context:component-scan base-package="com.powernode1.bean,com.powernode1.dao;com.powernode1.service"/>
</beans>

测试

@Test
public void testGetUser(){
    ClassPathXmlApplicationContext beans = new ClassPathXmlApplicationContext("spring1.xml");
    User user = (User)beans.getBean("u");
    System.out.println("user = " + user);
}

  1. 依赖注入注解

依赖注入的前提:依赖类和被依赖都要被spring容器管理

@Autowired:依赖注入注解  它是按照类型注入

@Qualifier :是Autowired的辅助注解 标明注入的是那个类

//被依赖类
public interface UserDao {
    void addUser();
}

实现类:ud

//被依赖类
@Repository("ud")
public class UserDaoImpl implements UserDao {
    public void addUser(){
        System.out.println("这是UserDaoImpl中的添加*******方法");
    }
}

实现类:userDaoImpl1

//被依赖类
@Repository
public class UserDaoImpl1 implements UserDao {
    public void addUser(){
        System.out.println("这是UserDaoImpl1中的添加&&&&&&&方法");
    }
}

依赖类:

//UserService需要UserDao的支持   依赖UserDao
//UserService也是一个类  可以让spring容器帮忙
//依赖类
@Component
public class UserService {
    @Autowired
    @Qualifier("userDaoImpl1")
    //按照类型注入  UserDao   spring容器会在容器中找给类型的对象  并把地址值注入进来
    private  UserDao userDao;
    public void savUserService(){
        /*UserDao userDao = new UserDao();//耦合度过高*/

        userDao.addUser();
    }
}

测试:

@Test
public void testGetUS(){
    ClassPathXmlApplicationContext beans = new ClassPathXmlApplicationContext("spring1.xml");
    UserService userService = (UserService) beans.getBean("userService");
    userService.savUserService();
}

2.5、Spring的配置详解

Spring容器根据读取的配置文件,反射生成对象模型。根据对象模型创建对象

并把对象放入单例池中,我们每次取对象就是从单例池中获取对象

Spring开发中主要是对Bean的配置,Bean的常用配置一览如下:

Scope:属性,当前类的创建方式 是单例还是多例  默认是单例模式

默认情况下,单纯的Spring环境Bean的作用范围有两个:

Singleton和Prototype

singleton:单例,默认值,Spring容器创建的时候,就会进行Bean的实例化,并存储到容器内部的单例池中,每次getBean时都是从单例池中获取相同的Bean实例;

prototype:原型,Spring容器初始化时不会创建Bean实例,当调用getBean时才会实例化Bean,每次getBean都会创建一个新的Bean实例。

当scope设置为singleton时,获得两次对象打印结果是一样的

<!--默认调用无参构造创建对象-->
<bean id="u" class="com.powernode.bean.User" scope="prototype"/>

Lazy-init:属性 懒加载    默认是false  饿汉式

ApplicationContext接口是单例饿汉式   BeanFactory是单例懒汉式

单例对象可以设置懒加载

<!--默认调用无参构造创建对象-->
<bean id="u" class="com.powernode.bean.User" scope="singleton" lazy-init="true"/>

懒加载和多例的注解方案:

@Component("user")//在spring容器中  它的唯一标识是u
//@Lazy//当你在这个类上引入lazy注解 就是想让该类懒加载
@Scope("prototype")
public class User {
    private int uid;
    private String uname;
    private String ucode;
    private String upwd;

 3.Spring的生命周期

Spring Bean的生命周期是从 Bean 实例化之后,即通过反射创建出对象之后,到Bean成为一个完整对象,最终存储到单例池中,这个过程被称为Spring Bean的生命周期。Spring Bean的生命周期大体上分为三个阶段:

1、 Bean的实例化阶段:Spring框架会取出BeanDefinition的信息进行判断当前Bean的范围是否是singleton的,是否不是延迟加载的,是否不是FactoryBean等,最终将一个普通的singleton的Bean通过反射进行实例化;

2、Bean的初始化阶段:Bean创建之后还仅仅是个"半成品",还需要对Bean实例的属性进行填充、执行一些Aware 接口方法、执行BeanPostProcessor方法、执行InitializingBean接口的初始化方法、执行自定义初始化init方法等。该阶段是Spring最具技术含量和复杂度的阶段,Aop增强功能,Spring的注解功能等、spring高频面试题Bean的循环引用问题都是在这个阶段体现的;

3、 Bean的完成阶段:经过初始化阶段,Bean就成为了一个完整的Spring Bean,被存储到单例池 singletonObjects中去了,即完成了Spring Bean的整个生

命周期。

 

 4.Spring的核心功能:AOP

AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程序运行过程。 AOP 底层,就是采用动态代理模式实现的。

采用了两种代理:JDK 的动态代理,与 CGLIB 的动态代理。

面向切面编程本质上还是面向对象编程,只是这里对象的调用使用的动态代理

面向切面编程,就是将交叉业务逻辑封装成切面,利用 AOP 容器的功能将切面织入到主业务逻辑中

面向切面编程需要三个要点  :1、切点  2、切面类中的函数  3、通知方式  三者合在一起叫织入

面向切面编程对有什么好处?

1.减少重复;

2.专注业务;

注意:面向切面编程是面向对象编程的一种补充一种升华。

使用 AOP 减少重复代码,专注业务实现:

 

4.1、搭建spring的aop环境

Aop实在spring容器的基础上建立的

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值