Spring学习

入门案例

建立Java工程,导入如下Java包。

Spring学习
创建User类
public class User {
    public void add(){
        System.out.println("add....");
    }
}

在src目录下编写xml配置文件


编写测试类

@Test
    public void test1(){
        //1.读取配置文件 在src下可以用这个方法
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        //2.获取对象
        User user = context.getBean("user", User.class);
        //3.拿对象操作值
        System.out.println(user);  //com.hyq.User@33f88ab
        user.add();
    }

IOC 控制反转

两个核心接口 BeanFactory,ApplicationContext

1、IOC思想基于IOC容器完成,IOC容器底层就是 对象工厂
2、Spring 提供IOC容器实现两种方式:(两个接口)
(1)BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用。 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
(2)ApplicationContext它是BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用 加载配置文件时候就会把在配置文件对象进行创建

ApplicationContext 继承关系

Spring学习

这里 ClassPathXmlApplicationContextFileSystemXmlApplicationContext都是加载xml文件的类
其中当 xml位于 src目录或者子目录下时,可以使用 ClassPathXmlApplicationContext来加载xml文件,当xml位于磁盘某个位置,如C盘下时可以使用 FileSystemXmlApplicationContext(要写全路径,即绝对路径)来加载xml文件.

Bean管理

主要是两个操作:① spring创建对象 ② spring注入属性 就是类中set操作
主要实现:① 基于配置文件xml方式实现 ② 基于注解实现


DI依赖注入

作用:注入属性。方式:① 通过set注入 ② 通过有参构造器注入 ③ 通过spring配置文件注入

创建User类

package com.hyq;

public class User {
    private String name;
    private String author;

    public void setName(String name) {
        this.name = name;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

配置xml文件.要想通过xml注入, User类必须有set方法


P注入

首先在xml中需要这样的操作:

Spring学习

编写 web.xml配置文件,仍然用上面的测试类


注入空值和特殊值

编写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">

    <!--配置User对象-->
    <bean id="user" class="com.hyq.User">
        <!--<property name="name" value="hyq">-->
        <!--</property>-->
        <!--①注入空值;②如果不写默认也是注入的空值-->
        <property name="name">
            <null></null>
        </property>
        <!--法一:注入特殊值-->
        <!--<property name="author" value="<你好!>">-->
        <!--</property>-->
        <!--法二:注入特殊值 语法:<![CDATA[ 填写你要注入的内容 ]]-->
        <property name="author">
            <value><!--[CDATA[ <你好!> ]]--></value>
        </property>
    </bean>
</beans>

内/外部bean的注入

编写Dept类和Employee类

// Dept类
public class Dept {
    private String dname;

    public void setDname(String dname) {
        this.dname = dname;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "name='" + dname + '\'' +
                '}';
    }
}
//Employee类
public class Employee {
    private String name;
    private int age;
    private Dept dept;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", dept=" + dept +
                '}';
    }
}

配置xml 这里的dept和employee没有重名属性


编写测试类

Spring学习
结果输出 Employee{name='hyq', age=3, dept=Dept{name='&#x4EBA;&#x4E8B;&#x90E8;'}}

集合注入

编写实体类

/**
 * &#x96C6;&#x5408;&#x7684;&#x6CE8;&#x5165;
 */
public class MyCollection {
    private String[] course;
    private List<string> list;
    private Map<string,string> map;
    private Set 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 set) {
        this.set = set;
    }

    @Override
    public String toString() {
        return "MyCollection{" +
                "course=" + Arrays.toString(course) +
                ", list=" + list +
                ", map=" + map +
                ", set=" + set +
                '}';
    }
}

</string,></string></string,string></string>

编写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">

    <!--集合的注入-->
    <bean id="myCollection" class="com.testDemo.collections.MyCollection">
        <!--数组的注入-->
        <property name="course">
            <array>
                <value>&#x8BED;&#x6587;</value>
                <value>&#x6570;&#x5B66;</value>
            </array>
        </property>
        <!--list注入-->
        <property name="list">
            <list>
                <value>Chinese</value>
                <value>USA</value>
            </list>
        </property>
        <!--map注入-->
        <property name="map">
            <map>
                <entry key="key1" value="value1"></entry>
                <entry key="key2" value="value2"></entry>
            </map>
        </property>
        <!--set注入-->
        <property name="set">
            <set>
                <value>set1</value>
                <value>set2</value>
            </set>
        </property>
    </bean>

</beans>

编写测试类

Spring学习

结果输出: MyCollection{course=[&#x8BED;&#x6587;, &#x6570;&#x5B66;], list=[Chinese, USA], map={key1=value1, key2=value2}, set=[set1, set2]}

单例和原型模式

spring中设置创建的bean默认是单例模式。【单例模式:加载spring配置文件时,对象已经创建好了】

例如:配置user的属性值后

Spring学习
测试:
Spring学习
结果输出的地址相同:
Spring学习

spring中可以通过scope设置它的设计模式,可以设为原型模式(prototype)【原型模式:在调用getBean方法时创建了多实例对象】

Spring学习
再次测试 地址不同
Spring学习

Bean的生命周期

① 通过构造器创建bean实例
② 为bean的属性设置值以及对其它bean的引用(调用set方法)
③ 把bean实例传递给bean后置处理器方法 postProcessBeforeInitialization
④ 调用bean初始化方法(需要配置)
⑤ 把bean实例传递给bean后置处理器方法 postProcessAfterInitialization
⑥ 使用bean进行操作
⑦ 当容器关闭时,调用bean的销毁方法(需要配置)

自动装配

定义一个类

Spring学习

原始写法:手动注入

Spring学习
自动注入 byName
Spring学习
自动注入:byType
Spring学习

引入外部文件进行属性的注入

例如数据库的配置
首先引入Druid的jar包

Spring学习
编写外部配置文件mysql.properties
Spring学习
编写xml配置文件
Spring学习

基于注解的对象配置

/**
 spring中针对bean管理**创建对象**提供的注解:@Component,@Service,@@ontroller,@Reposity
  这几个注解都是让spring来创建对象用的
  在类上配置此属性相当于 xml中的
*/

1. 引入spring的aop的包,只有引入了此包,注解才能生效

Spring学习
2. 在xml中配置要扫描的注解
Spring学习
编写UserService一个类
Spring学习
编写测试类
Spring学习

注解扫描的其他问题

Spring学习

Spring学习

基于注解的属性注入

① @Autowired: 根据 属性类型进行自动装配
② @Qualifier(限定符/修饰符): 根据 属性名进行注入,需要配合@Autowired使用
③ @Resource: 既可以根据类型注入,也可以根据名称注入 该注解位于 javax.annotation包下
④ @Value: 注入 普通类型的属性

编写ADao接口

Spring学习
编写ADao的实现类
Spring学习
现在要在Service层要调用Dao层
Spring学习
value注解的使用,只能注入基本数据类型
Spring学习

完全注解开发

Spring学习

AOP面向切面编程

AOP的术语
① 连接点:类里面有哪些方法可以被增强,这些方法叫做连接点
② 切入点:实际被真正增强的方法,叫切入点。 有时一个类中有多个方法,但是只需要增强一个方法,那么该方法就称之为切入点。
③ 通知(增强):(1)实际增强的逻辑部分称为通知
(2)通知有多种类型:前置通知,后置通知,环绕通知,异常通知,最终通知
④ 切面:把通知应用到切入点

引入aspectj所需要的包

Spring学习

基于注解实现AOP

切入点表达式

execution(&#x6743;&#x9650;&#x4FEE;&#x9970;&#x7B26;&#x3010;&#x53EF;&#x9009;&#x3011; &#x8FD4;&#x56DE;&#x503C;&#x7C7B;&#x578B;&#x3010;&#x5FC5;&#x586B;&#x3011; &#x7C7B;&#x5168;&#x8DEF;&#x5F84;&#x540D;&#x79F0;&#x3010;&#x53EF;&#x9009;&#x3011; &#x65B9;&#x6CD5;&#x540D;&#x79F0;&#x3010;&#x5FC5;&#x586B;&#x3011;(&#x53C2;&#x6570;&#x5217;&#x8868;&#x3010;&#x6CA1;&#x6709;&#x53C2;&#x6570;&#x53EF;&#x4E0D;&#x586B;&#x3011;))

1.编写User类和需要增强的UserProxy类

Spring学习
Spring学习
2.编写xml配置文件
Spring学习
编写测试类
Spring学习
测试结果
Spring学习

现在测试四种通知的顺序;编写代理类

package com.aop.aopanno;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 这里是增强User的类
 */
@Component
@Aspect //生成代理对象 这里代理User类
public class UserProxy {

    //前置通知 增强User中的add()方法
    @Before(value = "execution(public void com.aop.aopanno.User.add(..))")
    public void addBefore(){
        System.out.println("添加之前的通知");
    }

    @After(value = "execution(* com.aop.aopanno.User.add(..))")
    public void addAfter(){
        System.out.println("添加之后的通知");
    }

    @Around(value = "execution(* com.aop.aopanno.User.add(..))")
    public void addAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前");
        //让增强的那个方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后");
    }

    @AfterReturning(value = "execution(* com.aop.aopanno.User.add(..))")
    public void addAfterReturning(){
        System.out.println("afterReturning..");
    }
}

仍然用上面的测试方法,输入结果为:(要知道执行顺序)

Spring学习

@AfterThrowing 只有在抛出异常才会执行

相同切入点抽取

Spring学习

多个增强类要对同一个方法进行增强,可以设置优先级

现在多了一个UserProxy1类,也要对add()方法进行增强,我们可以设置让谁先实现add方法

Spring学习
Spring学习
执行结果:
Spring学习

基于配置文件实现AOP

编写Book类和BookProxy类

Spring学习
Spring学习
编写book.xml配置文件

Spring学习
Spring学习

jdbcTemplate

1.首先引入Java包

Spring学习
2.编写Book实体类
Spring学习
3. 编写Book Dao接口类
Spring学习
4. 编写BooKDaoImpl的实现类
Spring学习
5. 编写bookService类
Spring学习
外部数据文件mysql.properties
Spring学习

6. 开启扫描注解和配置jdbcTemplate对象,数据源等


事务( PlatformTransactionManager )

事务的特性(ACID)

① 原子性:要么都成功,要么都失败
② 一致性:总量不变,A有100元,B有100元,A,B一共有200元,A给B转钱,最后的总量还是200
③ 隔离性:多事务 操作不会产生影响.要解决三个问题:脏读,不可重复读,幻读
脏读:一个未提交事务读取到另一个未提交事务的数据
不可重复读:一个未提交事务读取到另一提交事务 修改的数据
幻读:一个未提交事务读取到另一提交事务 添加的数据
④ 持久性:提交存入数据库后不可变。

总结:①事务一般加到业务层

声明式事务管理(底层用AOP原理)分为:基于注解,基于xml配置文件

  • 1.基于注解

    步骤:xml中需要如下配置:① 创建事务对象 ② 开启事务注解 ③ 在需要的类上或者方法上加上@Transactional,这里在Service类上加该注解。如下例子

所用数据库表

Spring学习
编写Account类
Spring学习
编写AccountDao接口
Spring学习
编写AccountDaoImpl的实现类
Spring学习
编写Service类
Spring学习
编写xml配置文件

Spring学习

编写测试类

Spring学习

*
1. 基于xml配置文件

步骤:① 创建事务对象 ② 配置通知tx:advice ③ 配置切入点

xml配置文件如下


将Service中的@Transactional注解去掉

Spring学习

Original: https://www.cnblogs.com/huyuqing/p/14534429.html
Author: 先生胡
Title: Spring学习

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/567177/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球