【Spring】Spring的核心思想IOC和AOP

目录

什么是Spring

Spring的优势

使用SpringIOC容器管理JavaBean步骤

xml版本

SpringIOC

SpringDI

set注入实现步骤:

构造注入DI实现步骤:

springIOC容器对bean管理

一、Bean的自动装配

二、bean的实例化

三、bean的生命周期(单例)

四.bean的作用域

注解版本

 一.注入类

二.注入数据

三.其他注解

四、javaConfig配置类注解

SpringAOP

AOP通知类型

SpringAOP的实现步骤

XML版

注解版


什么是Spring

spring框架是一个轻量级的框架,他的核心思想是IOC(Inverse  Of Control控制反转)AOP(Aspect  Oriented 面向切面编程)。为Java应用程序开发提供组件管理服,用于组件之间的解耦。以及简化第三方JavaEE中间件的使用(JMS,任务调度,缓存,ORM框架),是一个基础架构型的开发框架。

Spring的优势

  • 方便解耦,简化开发
            通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
  • AOP编程的支持
            通过 Spring 的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付
  • 声明式事务的支持
            可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务的管理,提高开发效率和质量。
  • 方便程序员的测试
            可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。
  • 方便集成各种优秀框架
            Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(SpringMVC、Mybatis、Hessian、Quartz 等)的直接支持。
  • 降低JavaEE API的使用难度
            Spring 对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。
  • Java源码时经典学习案例

编程为了符合企业级标准,高聚合,低耦合
而Spring第一大核心思想就是IOC-控制反转 DI-依赖注入
SpringIOC容器:将所有的JavaBean注入Spring容器进行"解耦"管理,Spring万物皆为Bean

搭建Spring环境的步骤有两步-坐标的导入配置文件的创建 

<!--spring坐标-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.26</version>
</dependency>

使用SpringIOC容器管理JavaBean步骤

xml版本

配置文件

<?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>
  1. 创建JavaBean
  2. 将类注入Spring容器
            配置语法:<bean id="唯一标识" class="类的完全限定名称"></bean>
  3. 测试
            加载Spring主配置文件获取核心对象
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("配置文件名.xml");
            让Spring已解耦的方式进行对象的实例化返回用户
            applicationContext.getBean("id");

SpringIOC

IOC的名词解释,作用是解耦,使用IOC容器管理项目组件的耦合关系

IOC(Inversion Of Control,中文解释控制反转)是 Spring框架的核心思想之一,主要用于解耦。IOC是                 
由Spring框架根据配置文件或者注解来创建Bean对象并管理Bean对象之间的依赖关系。使对象形成松散的关系,实现解耦。

控制指的是创建对象的控制权

反转指的是将控制权交给其他外部环境(Spring框架,IOC容器)。

SpringDI

DI(Dependecy Inject,中文解释依赖注入)是对IOC概念的不同角度的描述,
指应用程序描述时,每个Bean对象在被IOC容器注入前都会依赖于另一个Bean对象。

DI的实现方式:

  1. set注入------->通过set方法维护对象之间的依赖关系
  2. 构造注入----->通过构造方法维护对象之间的依赖关系
  3. 属性注入----->不推荐

DI注入的数据类型:

  1. 注入对象
  2. 注入基本对象与String
  3. 注入复杂对象 list、set、array、map、properties 

set注入实现步骤:

首先需要给属性提供set的方法,并在Bean标签中配置

配置位置:<bean>此位置</bean>

配置语句:<property 属性名="属性值"></property>

配置属性:
        name======》属性名称
        value=====》属性值
        ref=======》属性值的引用

构造注入DI实现步骤:

给属性提供构造方法,在bean标签内部开启配置

配置位置:<bean>此位置</bean>

配置语法:<constructor-arg 属性名="属性值"></constructor-arg>

配置属性:
        name======》构造方法参数名称
        index=====》构造方法参数下标
        type======》构造方法参数类型
        value=====》属性值
        ref=======》属性值的引用

springIOC容器对bean管理

一、Bean的自动装配

语法:
        autowire="属性值"
        default-autowire="属性值"

位置:
        bean标签---->局部设置
        beans标签--->全部设置

属性:
        byName============>通过set方法按照名称自动装配,属性名称与bean的id
        byType============>通过set方法按照类型自动装配,属性类型与bean的class
        constructor=======>通过构造方法按照自动装类型配,属性类型与bean的class

注意:

  1. 全局,局部均设置,则就近原则
  2. 大型项目不建议使用,自动装配可读性低
  3. 自动装配一般只装配javaBean

二、bean的实例化

        2.1通过类的无参构造方法实例化(默认)
        2.2通过指定工厂创建对象
        2.3通过指定静态工厂创建对象 

三、bean的生命周期(单例)

  1. 实例化
  2. 属性赋值
  3. 初始化
    3.1接口初始化InitializingBean
    3.2属性初始化init-method
  4. 操作使用
  5. 销毁
    5.1接口销毁DisposableBean
    5.2属性销毁destory-method

四.bean的作用域

        prototype--->单例
        singleton--->多例
        session----->会话
        request----->请求

注解版本

 一.注入类

@Component
含义:将注解所修饰的类注入spring容器
位置:类
语法:@Component(value = "id") 如果省略value="id"默认注入的id为类的名称且首字母小写
注意:不可以单独使用 <context:component-scan base-package=""></context:component-scan>

@Repository 注入数据访问层

@Service 注入业务层

@Controller 注入控制层

以上三个注解与@Component功能语法一致

二.注入数据

@Value()
含义:向属性注入基本类型与String
语法:@Value("数据") @Value("${key}")
位置:属性
注意:不能单独使用 <context:property-placeholder location=""></context:property-placeholder>

@Autowired()
替换:自动装配属性
位置:属性
含义:通过“set”方法【set方法可以省略】,按照“类型”自动装配,如果类型冲突则按照"名称"装配
注意:

  1. 按类型装配如果冲突切换为名称装配
  2. 按类型装配如果冲突切换为名称装配,如果名称也没有则会抛异常 NoUniqueBeanDefinitionException
  3. 按类型装配没一个匹配 NoSuchBeanDefinitionException 

三.其他注解

@Primary
含义:在类型装配冲突的情况下,此注解所修饰的类作为首选项
位置:类
注意:不能单独用

@Qualifier
含义:按照名称装配
位置:属性
注意:不能单独用

@Resource
含义:按照名称装配
位置:属性
注意:单独用

@Scope
含义:作用域
位置:类
注意:不能单独用
举例:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

@PreDestroy
含义:替换destory-method
位置:方法
注意:单独用

@PostConstruct
含义:替换init-method
位置:方法
注意:单独用

四、javaConfig配置类注解

@Configuration
含义:配置类
注意:AnnotationConfigApplicationContext

@ComponentScan(basePackages="com.cc")
替换:<context:component-scan base-package=""></context:component-scan>

@PropertySource("classpath:文件名.properties")
替换:<context:property-placeholder location=""></context:property-placeholder>

@Import(配置类.class)
含义:导入其他配置类

@Bean
含义:注入类;方法返回值为class 方法名称为id
位置:修饰方法
注意:单独使用无需扫描

SpringAOP

 AOP(Aspect-Oriented Programming: 面向切面编程):将那些与业务无关, 却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽 取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的 重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;

Spring AOP 基于动态代理实现:

  • 如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象(JDK动态代理的核心是InvocationHandler接口和Proxy类);
  • 如果被代理的对象,没有实现某个接口,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理(Cglib动态代理的核心是MethodInterceptor接口和Enhancer类);

AOP通知类型

AOP将抽取出来的共性功能称为通知;通知类型:以通知在上下文中的具体位置作为划分

前置通知(Before)

后置通知(After)

返回通知(After-returning)

异常通知(After-throwing)

环绕通知(Around) 

 

 

AOP连接点(Join point):AOP将所有的方法都视为连接点,不管是接口里面的抽象方法,还是实现类里面的重写方法,都是连接点

AOP切点(Pointcut):AOP将可能被抽取共性功能的方法称为切入点。切入点是连接点的子集

AOP目标对象(Target):就是挖掉功能的方法对应的类生的对象,这种对象是无法直接完成最终工作的

AOP织入(Weaving):就是将挖掉的功能回填的动态过程

AOP切面:切点+通知

SpringAOP的实现步骤

坐标

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.28</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
</dependency>

XML版

切点表达式配置语法:
execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))
        eg: execution(public void com.apesource.service.ServiceImp.findAll())

1.修饰符可以省略代表任意
         execution(返回值 包名称.类名称.方法名称(参数列表))

2.返回值可以使用“*”代表任意
         execution(* 包名称.类名称.方法名称(参数列表))

3.包名可以使用“*”代表任意名称
         execution(* *.*.*.类名称.方法名称(参数列表))

4.包名可以使用“..”代表任意个数
         execution(* *...类名称.方法名称(参数列表))

5.类名与方法名可以使用“*”代表任意
         execution(* *...*.*(参数列表))

6.参数列表可以使用".."代表任意个数任意类型
         execution(* *...*.*(..))
         如果有参数
                 int======>int
                 String===>java.lang.String

总结AOP开发过程:
开发阶段(开发者完成)===========我们自己做

  • 正常的制作程序
  • 将非共性功能开发到对应的目标对象类中,并制作成切入点方法
  • 将共性功能独立开发出来,制作成“通知”
  • 在配置文件中,声明“切入点”
  • 在配置文件中,声明"切入点"与"通知"间的关系(含通知类型),即"切面"

运行阶段(AOP完成)=============spring帮我们做的

  • Spring容器加载配置文件,监控所有配置的“切入点”方法的执行
  • 当监控到“切入点”方法被运行,使用“代理”机制,动态创建“目标对象”的“代理对象”,根据“通知类别”,在“代理对象”的对应位置将“通知”对应的功能“织入”,完成完整的代码逻辑并运行 
<!--开启aop配置-->
    <aop:config>
        <!--切面-->
        <aop:aspect id="main" ref="loggerUtil">
            <!--切点-->
            <aop:pointcut id="dian" expression="execution(* com.apesource.service.ServiceImp.*(..))"/>
            <!--前置通知-->
            <aop:before method="beforeMethod" pointcut-ref="dian"></aop:before>
            <!--返回通知-->
            <aop:after-returning method="afterRrturnMethod" pointcut-ref="dian"></aop:after-returning>
            <!--异常通知-->
            <aop:after-throwing method="throwMethod" pointcut-ref="dian"></aop:after-throwing>
            <!--后置通知-->
            <aop:after method="afterMethod" pointcut-ref="dian"></aop:after>
            <!--环绕通知-->
            <aop:around method="arroundMethod" pointcut-ref="dian"></aop:around>


        </aop:aspect>
    </aop:config>

注解版

@Aspect(切面)

@Pointcut(value = "execution(* com.cc.service.*.*(..))")(切点,需要配合一个类使用,类名为id)

@Before("dian()")(前置通知)

@AfterReturning("dian()")(返回通知)

@AfterThrowing("dian())")(异常通知)

@After("dian()")(后置通知)

@Around("dian()")(环绕通知,使用注解的话比较推荐环绕通知)

@EnableAspectJAutoProxy(AOP的自动代理,使用注解版时需要写在配置类中)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值