Spring学习笔记:IOC控制反转、AOP面向切面

挺快的,框架这一部分


一、Spring概述

轻量级的 开源的 J2EE框架

IOC: 将创建对象的过程交给Spring来管理[控制反转]

AOP: 面向切面编程,不修改源代码的情况让你的程序增强.

Spring框架的特点

简化开发
aop的支持
方便和其他的框架进行整合
方便进行事务操作

入门案例

导入依赖包

在src下写配置文件

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

创建普通类和测试类

public class User implements Serializable {
    public void sayHello(){
        System.out.println("Hello Java之神!");
    }
}

在上面配置文件的beans标签里面写bean标签

//id是起个名字,class是类名路径
<bean id="user" class="User"/>

在测试类中调用sayHello方法

    @Test
    public void testBean(){
		//获取配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		//调用获得实例
        User user = applicationContext.getBean("user", User.class);
		//调用实例的方法
        user.sayHello();
    }

二、IOC(控制反转)

IOC底层

  • 1.xml解析
  • 2.工厂模式
  • 3.反射

入门案例就是一个控制反转的例子,就是把创建对象的过程交给对象工厂。

Spring 提供IOC实现一共有两种方式:

BeanFactory(了解

是框架内部使用的接口,不提供给开发者 加载配置文件的时候不会创建对象,只有获取对象的时候才会创建。

ApplicationContext(重点
这个是面对开发者的,是BeanFactory接口的子接口,功能更强大。 加载配置文件的时候就会将对象创建出来。

2.1 IOC bean 的XML操作(创建对象,注入属性

属性注入

<!--  set注入  -->
    <bean id="user1" class="User">
        <property name="name" value="我是set注入"/>
        <property name="id" value="1"/>
    </bean>
    
<!--  构造注入  -->
    <bean id="user2" class="User">
        <constructor-arg name="id" value="2"/>
        <constructor-arg name="name" value="我是构造注入"/>
    </bean>

<!--  p 命名空间注入 ( -->
    <bean id="user3" class="User" p:id="3" p:name="我是p 命名空间注入"/>

级联赋值

<!--  级联赋值  -->
    <!--  第一种方式  -->
    <bean id="emp" class="entity.Emp">
        <property name="name" value="idiot"/>

        <property name="dept">
            <bean class="entity.Dept">
                <property name="name" value="地球人事管理"/>
            </bean>
        </property>
    </bean>
    
    <!--  第二种方式  -->
    <bean id="emp" class="entity.Emp">
        <property name="name" value="idiot"/>
        <property name="dept" ref="dept"/>
    </bean>
    <bean id="dept" class="entity.Dept">
        <property name="name" value="宇宙管理分局"/>
    </bean>

特殊类型处理

public class Demo implements Serializable {
    private String [] strings;
    private List<String> lists;
    private Map<String,String> maps;
    private Set<String> sets;
}
    <bean id="demo" class="entity.Demo">
        <!--处理List-->
        <property name="lists">
            <list>
                <value> list1 </value>
                <value> list2 </value>
            </list>
        </property>
        <!--处理Map-->
        <property name="maps">
            <map>
                <entry key="1" value="map1"/>
                <entry key="2" value="map2"/>
            </map>
        </property>
        <!--处理Array-->
        <property name="Strings">
            <array>
                <value> String1 </value>
                <value> String2 </value>
            </array>
        </property>
        <!--处理set-->
        <property name="sets">
            <set>
                <value> set1 </value>
                <value> set2 </value>
            </set>
        </property>
    </bean>

scope=“prototype” 多实例
scope=“singleton” 默认情况 单实例
例子

bean生命周期:

    1. 执行无参构造
    1. 执行set方法设置值
    1. 执行初始化方法(init-method
    1. 获取bean的实例对象
    1. 执行销毁的方法 (destroy-method

自动装配autuwire

  • byName : 根据属性名注入,要求注入bean的id 值要和类的属性名保持一致!!
  • byType : 根据类型注入

2.2 IOC bean 的 注解 操作

Spring框架中提供的关于创建bean的注解 :
@Component
@Service
@Controller
@Repository

四个注解的功能是一样的,都可以用来创建bean的实例

@Autowired 自动配置

@Service
public class Emp implements Serializable {
    private String name;
    @Autowired //这个注解可以自动装配默认采用 byType,即会寻找该类的bean自动注入,不存在的话会抛出异常
    private Dept dept;
}

使用注解要先扫描

<context:component-scan base-package="entity"/>

三、AOP(面向切面)

AOP底层是动态代理

  1. 有接口 使用jdk动态代理
  2. 无接口 使用cglib动态代理

AOP 术语
连接点:

类里面的哪些方法可以被增强,那么这个方法称为连接点

切入点:

实际被真正增强的方法,称为切入点

切面:

把通知应用到切入点的过程称为切面

通知[增强]:

实际增强的逻辑部分称为通知

通知的类型:

  • 前置通知
  • 后置通知
  • 环绕通知
  • 异常通知
  • 最终通知
准备开发:
   Spring的aop是基于 AspectJ 实现aop操作的
   AspectJ 不是Spring的组成部分,独立的AOP框架,将AspectJ 和Spring框架一起使用,进行AOP操作。

3.1 切入点表达式

execution([访问修饰符][返回值类型][类的全路径][方法名][(形参列表)])

execution(* entity.Person.song(..))

3.2 xml 实现AOP

    <bean id="person" class="entity.Person"/>
    <bean id="personProxy" class="entity.PersonProxy"/>

    <aop:config>
        <aop:pointcut id="p" expression="execution(* entity.Person.song(..))"/>
        <aop:aspect ref="personProxy">
            <aop:before method="before" pointcut-ref="p"/>
            <aop:after method="after" pointcut-ref="p"/>
            <aop:around method="around" pointcut-ref="p"/>
            <aop:after-returning method="afterReturning" pointcut-ref="p"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="p"/>
        </aop:aspect>
    </aop:config>

3.3 注解实现AOP

还是要先扫描

<context:component-scan base-package="entity"/>

然后要打开自动代理

<aop:aspectj-autoproxy/>

代理类

@Component
@Aspect //这个不要忘记了,要确定切面
public class PersonProxy {

    @Before("execution(* entity.Person.song(..))")
    public void before(){
        System.out.println("唱前准备:前置通知");
    }

    @After("execution(* entity.Person.song(..))")
    public void after(){
        System.out.println("散伙!:最终通知");
    }

    @Around("execution(* entity.Person.song(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("立体音响:环绕通知前半场");
        proceedingJoinPoint.proceed();
        System.out.println("立体音响:环绕通知后半场");
    }

    @AfterReturning("execution(* entity.Person.song(..))")
    public void afterReturning(){
        System.out.println("唱后收拾:后置通知");
    }

    @AfterThrowing("execution(* entity.Person.song(..))")
    public void afterThrowing(){
        System.out.println("突发状况!开始处理!:异常通知");
    }
}

学完了?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值