Spring

Spring简介

  • Spring并不是一个包含大量新技术的框架, 而是抽象了大量javaEE应用中的常用代码, 将他们抽象成一个框架。
  • 你可以把Spring看成一个用来整合其他框架的框架
  • Spring本身提供了一个设计优良的MVC框架:springMVC  使用Spring 可以 直接用MVC 
  • 对于持久层(dao层【操作数据库层】)Spring 没有提供,但是可以无缝整合其他的 持久层框架如:MyBatis,Hibernate,JPA等,甚至可以直接使用JDBC,这也是Spring 的魅力所在,给开发者提供了大量了选择权。
  • 某种角度来说它更像一种容器,具有强大的生命力,贯穿三层。

Spring的具体优势

  1. 轻量级:Spring框架的核心库非常精简,不需要依赖庞大的第三方库,可以快速部署和运行,占用的系统资源也较少。
  2. 控制反转、依赖注入(IOC、DI):Spring通过IoC技术促进了代码的松耦合。对象之间的依赖关系由框架来管理,降低了类之间的紧耦合度,提高了代码的灵活性和可测试性。
  3. 面向切面编程(AOP):Spring提供了AOP支持,允许开发者将横切关注点(如日志、事务管理等)从业务逻辑中分离出来,提高了代码的可重用性和可维护性。
  4. 方便的测试:Spring对单元测试和集成测试提供了良好的支持。通过Spring的依赖注入和AOP等特性,可以方便地编写可测试的代码。
  5. 模块化和可扩展性:Spring框架采用分层的设计思想,将应用程序划分为不同的模块。这种模块化的设计使得应用程序更加易于维护和扩展。
  6. 支持声明式事务管理:Spring提供了事务管理的支持,允许开发者通过简单的配置来管理事务,而无需编写繁琐的事务管理代码。
  7. 丰富的功能模块:Spring框架提供了数据访问、事务管理、Web开发、安全性等多个功能模块,这些模块都经过了良好的设计和测试,可以方便地与Spring的核心模块集成。

Spring核心

  • Spring 容器管理 bean 各层对象,管理的是对象的声明周期和 对象的依赖关系(依赖注入)
  • 理解什么是依赖: 依赖就是一种关系,比如controller依赖 service  ,service 依赖 dao,也可以认为是A组件调用了B组件的方法,那么就认为A依赖B ,A可以多依赖
  • 依赖注入:用spring容器给Bean注入对象,也可以注入普通的属。这种方式是一种优秀的解耦方式,一配置文件的形式组织在一起,而不是硬编码的方式(service层 new 一个dao的实例),
  • 什么时控制反转:原本一个类需要一个对象时,要去主动获取,工厂里或者直接创建,现在只需要由Spring 给你被动的注入你需要的东西,所以控制的方式发生反转(与依赖注入完全一个东西理解角度不同罢了)

使用了Spring框架后:

程序员无须使用new调用构造器去创建对象。所有的Java对象都可以交给Spring容器去创建。

当调用者需要调用被依赖对象的方法时,调用者无须主动获取依赖对象,只要等待spring容器注入即可。

准备工作

        创建一个java maven 项目

        导入如下jar包

        注意junit  如果你想在非测试文件里面使用test  就把下面的限制范围搞没就行了(复制代码就行)

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.20</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

主备两个java  bean

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class People {
    private String name = "a_people";
    private Integer age;
    private Cat cat;
}

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Cat {
   private String name = "little_cat";
    private Integer age;
}


Spring 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">

<!--    spring 容器首先管理对对象的创建-->
<!--    1:无参构造创建对象-->
    <bean class="com.wolf.bean.Cat" id="cat"></bean>
    <bean class="com.wolf.bean.People" id="people"></bean>
</beans>

查看我们创建的javabean 和他们的关系 

test测试单元

通过类路径下  spring 文件名称找到  Spring 配置文件 生成容器对象

然后从容器中拿出通过无参构造创建的对象, 对象打印

        getBean("spring.xml里面定义的id值",  "对象的Class类")

public class Test01 {
    @Test
    public void test() throws Exception{
//        ApplicationContext 是应用上下文  即  spring 容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        Cat cat = ac.getBean("cat", Cat.class);
        People people = ac.getBean("people", People.class);
        System.out.println(cat);
        System.out.println(people);
    }
}

运行结果 

静态工厂创建Bean

工厂准备

一个接口 Flyable  和连个 实现类 CanFly  CannotFly  和一个 FlyFactory01工厂

public interface Flyable {
    public void fly();
}


public class CannotFly implements Flyable {
    @Override
    public void fly() {
        System.out.println("不可以飞");
    }
}


public class CanFly implements Flyable {
    @Override
    public void fly() {
        System.out.println("可以飞");
    }
}


public class FlyFactory01 {
    public static Flyable get(String choose){
        if("can".equalsIgnoreCase(choose)) {
            return new CanFly();
        }else if("cannot".equalsIgnoreCase(choose)){
            return new CannotFly();
        }else {
            return null;
        }

    }
}

xml文件

传入工厂类路径   id 为标识   工厂方法是你定义的 内部名为get 的方法  所以是get  

里面的标签是指  名称为choose 值为 can / cannot 的  参数(相当与调用了factory 的方法)

<!--    2.工厂方式  静态工厂方法-->
    <bean id="canA" class="com.wolf.factory01.FlyFactory01" factory-method="get">
        <constructor-arg value="can" name="choose"/>
    </bean>
    <bean id="cannotA" class="com.wolf.factory01.FlyFactory01" factory-method="get">
        <constructor-arg name="choose" value="cannot"/>
    </bean>

test类

public class TestStaticFactory {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        Flyable canA = ac.getBean("canA", Flyable.class);
        Flyable cannotA = ac.getBean("cannotA", Flyable.class);
        canA.fly();
        cannotA.fly();
    }
}

运行结果


非静态工厂创建Bean

参照上面的静态工厂的所有东西  

只是里面的 factory中静态方法换成  方法不能直接类调用  需要有实例

xml  

这个不同了 先创建一个工厂实例  再用 factory-bean 使用它   class 从工厂变为了 生成对象的 接口

<!--3.工厂方法-->
    <bean id="flyfactory02" class="com.wolf.factory01.Flyfactory02"></bean>
    <bean id="canB" class="com.wolf.factory01.Flyable" factory-bean="flyfactory02" factory-method="get">
        <constructor-arg name="choose" value="can"/>
    </bean>
    <bean id="cannotB" class="com.wolf.factory01.Flyable" factory-bean="flyfactory02" factory-method="get">
        <constructor-arg name="choose" value="cannot"/>
    </bean>

调用也是一样的  用id 和 接口就可以拿出来   调用方法即可

Spring注入(重点)

set注入和构造注入

新建两个javaBean

wolf  和 wolfKing

@Data
@ToString
public class Wolf {
    private String name;
    private Integer age;

    public Wolf() {
    }
}

@Data
@ToString
public class WolfKing {
    private String name;
    private Integer age;
    private Wolf wolf;
    private String[] hobbyArray;
    private List<Integer> scoreList;
    private Set<String> schoolSet;
    private Map<String, String> sizeMap;
    private Properties prop;

    public WolfKing() {
    }
}

xml

property 是set

constructor-arg 是构造进去的  

可以先构造再注入也行

里面的这些特殊数据也好办 都给了相应的标签了

<!--    set 和 构造注入-->
    <bean id="wolf01" class="com.wolf.bean.Wolf">
        <property name="name" value="little_wolf01"/>
        <property name="age" value="2"/>
    </bean>

    <bean class="com.wolf.bean.WolfKing" id="wolfKing">
        <property name="name" value="bigWolf"/>
        <property name="age" value="5"/>
<!--        ref  关联上面创建的wolf-->
        <property name="wolf" ref="wolf01"/>
<!--        string[] -->
        <property name="hobbyArray">
            <array value-type="java.lang.String">
                <value>football</value>
                <value>basketball</value>
                <value>swimming</value>
            </array>
        </property>
<!--        list<Integer>-->
        <property name="scoreList">
            <list value-type="java.lang.Integer">
                <value>100</value>
                <value>20</value>
            </list>
        </property>
<!--        set<String>-->
        <property name="schoolSet">
            <set value-type="java.lang.String">
                <value>嗷呜~!</value>
                <value>呜呜~~</value>
            </set>
        </property>
<!--        map<stirng,string>-->
        <property name="sizeMap">
            <map key-type="java.lang.String" value-type="java.lang.String">
                <entry key="aowu1" value="狠狠吃肉肉"/>
                <entry key="aowu2" value="狠狠睡觉觉"/>
            </map>
        </property>
        <property name="prop">
            <props>
                <prop key="IQ">666</prop>
                <prop key="EQ">555</prop>
            </props>
        </property>
    </bean>
<!--  构造创建-->
    <bean id="wolf02" class="com.wolf.bean.Wolf">
        <constructor-arg name="name" value="little_wolf"/>
        <constructor-arg value="1" name="age"/>
    </bean>
结果

一行太长了分开


用命名空间简化注入 + 多例和单例

    用命名空间简化配置  p:代表set注入   c:构造注入   
    scope 来调整 单例还是  多例 -> scope="prototype"  默认单例->  scope="singleton"

<?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:util="http://www.springframework.org/schema/util"
       xmlns:c="http://www.springframework.org/schema/c"
       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/util
       https://www.springframework.org/schema/util/spring-util.xsd">
<!--    用命名空间简化配置  p:代表set注入   c:构造注入   -->
<!--    scope 来调整 单例还是  多例 -> scope="prototype"  默认单例->  scope="singleton"-->
    <bean class="com.wolf.bean.Wolf" id="wolf01" p:name="little_aowu01" p:age="5" />
    <bean class="com.wolf.bean.Wolf" id="wolf02" c:name="little_aowu02" c:age="4" scope="prototype"/>

</beans>

外部设置一些集合util

<!-- 外部设置一些集合-->
    <util:map key-type="java.lang.String" value-type="java.lang.String">
        <entry key="key1" value="value1"/>
        <entry key="key2" value="value2"/>
        <entry key="key3" value="value3"/>
    </util:map>

自动注入autowire

        1.bytype 现在  狼王想匹配一只小狼  用自动配置通过类型匹配,  要求这个bean必须是唯一类型这里指的是wolf的bean只能有一个 第二个出现时 狼王的bean会报错  所以我注掉了

<?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 class="com.wolf.bean.Wolf" id="wolf01">
        <property name="name" value="little_wolf01"/>
        <property name="age" value="3"/>
    </bean>
    
<!--    <bean class="com.wolf.bean.Wolf" id="wolf02">-->
<!--        <property name="name" value="little_wolf02"/>-->
<!--        <property name="age" value="4"/>-->
<!--    </bean>-->

    <bean class="com.wolf.bean.WolfKing" id="wolfKing01" autowire="byType">
        <property name="name" value="wolfKing01"/>
    </bean>
</beans>

        2.byname 是允许多个 wolf 存在 但是必须有一个的 id 是wolf 顾名思义 byname通过类名来自动匹配 

        3.默认是 no  


操作数据库(重点)

druid连接池

先导包
  <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
druid 连接池的配置文件如下
mysql.driverClassName=com.mysql.cj.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mvnproject?useSSL=false&serverTimezone=Asia/Shanghai
mysql.username=root
mysql.password=123456
mysql.filters=stat
mysql.initialSize=2
mysql.maxActive=300
mysql.maxWait=60000
mysql.timeBetweenEvictionRunsMillis=60000
mysql.minEvictableIdleTimeMillis=300000
mysql.validationQuery=SELECT 1
mysql.testWhileIdle=true
mysql.testOnBorrow=false
mysql.testOnReturn=false
mysql.poolPreparedStatements=false
mysql.maxPoolPreparedStatementPerConnectionSize=200
xml文件如下

       先扫描druid.properties 配置文件 (property- placeholder 属性占位)

        才能在下面的配置中应用占位符 

init 和destroy  是 容器创建时 进行的方法  destroy 是销毁时执行的方法   这两个方法在 连接池jar包中以及写好了, 是方法 

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--    加载druid.propertis 配置文件-->
    <context:property-placeholder location="classpath:druid.properties"/>
<!--    set注入创建 dataSource 对象-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource
    init-method="init" destroy-method="close">
        <property name="driverClassName" value="${mysql.driverClassName}"/>
        <property name="url" value="${mysql.url}"/>
        <property name="username" value="${mysql.username}"/>
        <property name="password" value="${mysql.password}"/>
        <property name="initialSize" value="${mysql.initialSize}"/>
        <property name="maxActive" value="${mysql.maxActive}"/>
        <property name="maxWait" value="${mysql.maxWait}"/>
    </bean>
</beans>

 同样的里面也有工厂来创建 dataSource 对象    显然这个是静态工厂

管理JDBCTemplate

先导包

spring管理jdbc

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.20</version>
        </dependency>

 智能的maven 重复的会包会  omitted  忽略掉

xml

在之前的druid基础上  多加个配置 jdbc 即可

<!--    配置jdbc-->
    <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

续:  一般用springboot 后面 springboot + mybatis-plus + git + maven 组成项目 的核心后端框架 这个作为了解就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值