Spring5(一)IOC和AOP

1、Spring框架概述

1、Spring 是轻量级的开源的 JavaEE 框架
2、Spring 可以解决企业应用开发的复杂性
3、Spring 有两个核心部分:IOC 和 Aop
(1)IOC:控制反转,把创建对象过程交给 Spring 进行管理
(2)Aop:面向切面,不修改源代码进行功能增强
4、Spring 特点
(1)方便解耦,简化开发
(2)Aop 编程支持
(3)方便程序测试
(4)方便和其他框架进行整合
(5)方便进行事务操作
(6)降低 API 开发难度

入门案例

1.下载Spring5

在这里插入图片描述
2.下载
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
下载地址:https://repo.spring.io/artifactory/release/org/springframework/spring/5.2.16.RELEASE
在这里插入图片描述
3.打开idea,创建普通工程
在这里插入图片描述
导入相关jar包(从官网下载的工程的lib文件夹获取)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4、创建普通类,在这个类创建普通方法

public class User {
    
    
    public void say(){
    
    
        System.out.println("hello spring");
    }
}

5、创建 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">
   <!--配置User对象创建-->
    <bean id="user" class="com.yxm.User"></bean>
</beans>

6、进行测试代码编写
在这里插入图片描述

2、IOC容器

1、什么是IOC?
(1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
(2)使用 IOC 目的:为了耦合度降低
(3)做入门案例就是 IOC 实现
2、IOC底层原理
xml 解析、工厂模式、反射
3、IOC(BeanFactory接口)
1.IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
2.Spring提供IOC容器的两种方式:(两个接口)
(1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人
员进行使用
加载配置文件时候就会把在配置文件对象进行创建
3、ApplicationContext 接口有实现类
在这里插入图片描述

IOC操作Bean管理

什么是Bean管理

Bean管理指的是两个操作
1.Spring创建对象 2.Spring注入属性
Bean管理操作的两种方式
1.xml配置文件方式实现2.基于注解实现

IOC操作Bean管理(基于xml方式)

1.基于xml文件创建对象

在这里插入图片描述
(1)在Spring配置文件中,使用Bean标签,标签里面添加对应属性,就可以实现对象创建
(2)bean常用属性

  • id属性:唯一标识
  • class属性:类全路径
    (3)创建对象时候,默认也是执行无参构造方法创建对象
    2.基于xml方式注入属性
    (1)DI:依赖注入,就是注入属性
    第一种注入方式:使用set方法注入
package com.yxm;
public class Book {
    
    
    private String bname;
    //set注入
    public void setBname(String bname) {
    
    
        this.bname = bname;
    }
    //有参构造注入
    public Book(String bname){
    
    
        this.bname=bname;
    }
    public static void main(String[] args) {
    
    
        Book book=new Book("西游记");
        System.out.println(book.bname);
    }
}

第二种注入方式:在Spring配置文件配置对象创建,属性注入

    <!--配置Book对象创建-->
    <bean id="book" class="com.yxm.Book">
        <!--使用property完成属性注入-->
        <property name="bname" value="水浒传"></property>
    </bean>

第三种注入方式:通过有参构造注入
1.创建实体类对象

package com.yxm;
public class Order {
    
    
    private String name;
    private String address;
    //有参构造
    public Order(String name, String address) {
    
    
        this.name = name;
        this.address = address;
    }
}

2.在Spring配置文件进行配置

    <!--配置Order对象创建有参构造注入-->
    <bean id="order" class="com.yxm.Order">
        <constructor-arg name="name" value="笔记本"></constructor-arg>
        <constructor-arg name="address" value="浙江杭州"></constructor-arg>
    </bean>

p名称空间注入
使用p命名空间注入,可以简化基于xml配置
第一步:添加p空间在配置文件中

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

第二步:在bean标签进行属性注入

    <!--配置Book对象创建-->
    <bean id="book" class="com.yxm.Book" p:bname="红楼梦"></bean>

IOC操作Bean管理(xml注入其他类型属性)

1.字面量
(1)null值

    <!--配置Book对象创建-->
    <bean id="book" class="com.yxm.Book">
        <!--使用property完成属性注入-->
        <property name="bname" value="水浒传"></property>
        <property name="address">
            <null></null>
        </property>
    </bean>

(2)属性值包含特殊符号
将<>进行转义 &lt &gt

    <bean id="book" class="com.yxm.Book">
        <!--使用property完成属性注入-->
        <property name="bname" value="&lt;水浒传&gt;"></property>
        <property name="address" value="河南郑州"></property>
    </bean>

将特殊符号内容写进CDATA

    <bean id="book" class="com.yxm.Book">
        <!--使用property完成属性注入-->
        <property name="bname">
            <value><![CDATA[<水浒传>]]></value>
        </property>
        <property name="address" value="河南郑州"></property>
    </bean>

有点复杂,类似sql存储过程
2.注入属性–外部Bean
创建Service类和dao类
在Spring配置文件配置

   <bean id="userService" class="com.yxm.service.UserService">
      <property name="userDao" ref="userDaoImpl"></property>
   </bean>
   <bean id="userDaoImpl" class="com.yxm.dao.UserDaoImpl"></bean>

3.注入属性–内部Bean
一对多关系:部门和员工
部门类

package com.yxm;
//部门类
public class Dept {
    
    
    private String dname;
    public void setDname(String dname) {
    
    
        this.dname = dname;
    }
}

员工类

package com.yxm;
//员工类
public class Emp {
    
    
    private String ename;
    private String gender;
    private Dept dept;
    public void setEname(String ename) {
    
    
        this.ename = ename;
    }
    public void setGender(String gender) {
    
    
        this.gender = gender;
    }
    public void setDept(Dept dept) {
    
    
        this.dept = dept;
    }
}

在Spring文件进行配置

   <bean id="emp" class="com.yxm.Emp">
      <property name="ename" value="呆瓜"></property>
      <property name="gender" value=""></property>
      <property name="dept">
         <bean id="dept" class="com.yxm.Dept">
            <property name="dname" value="开发部"></property>
         </bean>
      </property>
   </bean>

级联赋值

   <bean id="emp" class="com.yxm.Emp">
      <property name="ename" value="呆瓜"></property>
      <property name="gender" value=""></property>
      <property name="dept" ref="dept"></property>
   </bean>
   <bean id="dept" class="com.yxm.Dept">
      <property name="dname" value="开发部"></property>
   </bean>

IOC操作Bean管理(xml注入集合属性)

注入数组,List集合,Map集合类型属性
创建实体类

public class Stu {
    
    
    private String[] course;
    private List<String> list;
    private Map<String,String> map;
    private Set<String> set;

    public void setCourse(String[] course) {
    
    
        this.course = course;
    }
    public void setList(List<String> list) {
    
    
        this.list = list;
    }
    public void setMap(Map<String, String> map) {
    
    
        this.map = map;
    }
    public void setSet(Set<String> set) {
    
    
        this.set = set;
    }
}

在Spring配置文件配置

   <bean id="stu" class="com.yxm.Stu">
      <!--数组-->
      <property name="course">
         <array>
            <value>java</value>
            <value>c++</value>
            <value>js</value>
         </array>
      </property>
      <!--list集合-->
      <property name="list">
         <list>
            <value>张三</value>
            <value>李四</value>
            <value>王五</value>
         </list>
      </property>
      <!--set集合-->
      <property name="set">
         <set>
            <value>吃饭</value>
            <value>睡觉</value>
            <value>打豆豆</value>
         </set>
      </property>
      <!--map集合-->
      <property name="map">
         <map>
            <entry key="1" value="java"></entry>
            <entry key="2" value="c"></entry>
         </map>
      </property>
   </bean>

IOC操作Bean管理(xml自动装配)

什么是自动装配?
根据指定装配规则(属性名称或属性类型),Spring自动将匹配的属性值进行注入
实现自动装配
bean标签属性autowire,配置自动装配
autowire属性常用两个值:
byName:根据属性名称注入,注入值bean的id和类属性名称一样
byType:根据属性类型注入
创建Emp类和Dept类

public class Emp {
    
    
    private  Dept dept;
    public void setDept(Dept dept) {
    
    
        this.dept = dept;
    }
    @Override
    public String toString() {
    
    
        return "Emp{" +
                "dept=" + dept +
                '}';
    }
    public void test(){
    
    
        System.out.println(dept);
    }
}

public class Dept {
    
    
    @Override
    public String toString() {
    
    
        return "Dept{}";
    }
}

创建配置文件

    <bean id="emp" class="com.yxm.Emp" autowire="byName"></bean>
    <bean id="dept" class="com.yxm.Dept" ></bean>

测试:

    @Test
    public void testautpwire(){
    
    
        ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");
        Emp emp=context.getBean("emp",Emp.class);
        System.out.println(emp);
    }

IOC操作Bean管理(外部属性文件)

1.不通过外部配置文件直接配置数据库信息
配置德鲁伊数据库连接池

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/sys"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

2.引入外部配置文件配置数据库信息
1.创建配置文件jdbc.properties

prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/sys
prop.username=root
prop.password=123456

2.把外部文件引入Spring配置文件
引入context名称空间

<?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"
       xmlns:p="http://www.springframework.org/schema/p"
       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/beans/spring-context.xsd">
    <context:property-placeholder location="classpath:jdbc.properties"/>
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${prop.driverClass}"></property>
            <property name="url" value="${prop.url}"></property>
            <property name="username" value="${prop.username}"></property>
            <property name="password" value="${prop.password}"></property>
        </bean>

IOC操作Bean管理(基于注解方式)

1.什么是注解?
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值, 属性名称=属性值…)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化 xml 配置
2、Spring 针对 Bean 管理中创建对象提供注解
(1)@Component(通用注解)
(2)@Service(Service层)
(3)@Controller(Controller层)
(4)@Repository(Dao层)

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

3、基于注解方式实现对象创建
1.引入依赖AOP
在这里插入图片描述
2.开启组件扫描

   <context:component-scan base-package="com.yxm.test"/>

3.创建类,在类上添加注解

@Component(value = "userService")
public class UserService {
    
    
    public void add(){
    
    
        System.out.println("service add");
    }
}

测试
在这里插入图片描述
4.基于注解方式实现属性注入
(1)@AutoWired:根据属性类型进行自动装配

@Service
public class UserService {
    
    
@Autowired
private UserDao userDao;
    public void add(){
    
    
        System.out.println("service add");
        userDao.add();
    }
}

(2) @Qualifer:根据属性名称进行注入
这个@Qualifier 注解的使用,和上面@Autowired 一起使用

  @Autowired
  @Qualifier(value = "userDaoImpl1")
    private UserDao userDao;
    public void add() {
    
    
        System.out.println("service add");
        userDao.add();
    }

(3) @Resource:可以根据类型或者名称注入

    @Autowired
    @Resource(name = "userDaoImpl1")
    private UserDao userDao;
    public void add() {
    
    
        System.out.println("service add");
        userDao.add();
    }

(4) @Value:注入普通属性

    @Value(value = "abc")
    private String name;

3、 AOP

什么是AOP?
AOP面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP相关术语
1.连接点:类里面哪些方法可以被增强,这些方法称为连接点
2.切入点:实际被增强的方法,成为切入点
3.通知(增强):实际增强的逻辑部分称为通知(增强)
通知分为:前置通知、后置通知、环绕通知、异常通知、最终通知
4.切面:是动作把通知应用到切入点过程
AOP操作
1.Spring框架一般基于AspectJ实现AOP操作
基于xml配置方式
基于注解(使用)
2.在项目工程引入AOP相关依赖
在这里插入图片描述
3.切入点表达式
(1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
(2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )
举例 1:对 com.yxm.dao.BookDao 类里面的 add 进行增强
execution(* com.yxm.dao.BookDao.add(…))
举例 2:对 com.yxm.dao.BookDao 类里面的所有的方法进行增强
execution(* com.yxm.dao.BookDao.* (…))
举例 3:对 com.yxm.dao 包里面所有类,类里面所有方法进行增强
execution(* com.yxm,.dao.. (…))
AOP 操作(AspectJ 注解)
1.创建类,在类里面定义方法

public class User {
    
    
    public void add(){
    
    
        System.out.println("add....");
    }
}

2.创建增强类(编写增强逻辑)
在增强类里面,创建方法,让不同方法代表不同通知类型

public class UserProxy {
    
    
    //前置通知
    public void before(){
    
    
        System.out.println("before.....");
    }
}

3.在配置文件进行通知配置
(1)在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"
       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/aop  http://www.springframework.org/schema/aop/spring-aop.xsd">
   <!--开启注解扫描-->
   <context:component-scan base-package="com.yxm.test.aop"/>
</beans>

(2)使用注解创建User和UserProxy对象
在这里插入图片描述
在这里插入图片描述

(3)在增强类上面添加注解 @Aspect
在这里插入图片描述
(4)在 spring 配置文件中开启生成代理对象

   <!--开启aspectj生成代理对象-->
   <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

4.配置不同类型的通知
(1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置

@Component
@Aspect
public class UserProxy {
    
    
    //前置通知
    @Before(value = "execution(* com.yxm.test.aop.User.add(..))")
    public void before(){
    
    
        System.out.println("before.....");
    }
    //后置通知(返回通知)
    @AfterReturning(value = "execution(* com.yxm.test.aop.User.add(..))")
    public void afterReturning(){
    
    
        System.out.println("afterReturning.....");
    }
    //最终通知
    @After(value = "execution(* com.yxm.test.aop.User.add(..))")
    public void after(){
    
    
        System.out.println("after.....");
    }
    //异常通知
    @AfterThrowing(value = "execution(* com.yxm.test.aop.User.add(..))")
    public void afterThrowing(){
    
    
        System.out.println("afterThrowing.....");
    }
    //环绕通知
    @Around(value = "execution(* com.yxm.test.aop.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    
    
        System.out.println("环绕之前.....");
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后.....");
    }
}

测试:
在这里插入图片描述
5.相同切入点抽取

    //切入点抽取
    @Pointcut(value = "execution(* com.yxm.test.aop.User.add(..))")
    public void pointcut(){
    
    
    }
    //前置通知
    @Before(value = "pointcut()")
    public void before(){
    
    
        System.out.println("before.....");
    }

6.有多个增强类同一个方法进行增强,设置增强类优先级
@Order注解实现,数字类型值越小优先级越高
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44226883/article/details/119272795
今日推荐