Spring

  • spring就是一个轻量级的控制反转(IOC)和面相切面编程(AOP)的框架。

环境搭建

maven导入依赖

org.springframework spring-webmvc 5.2.0.RELEASE org.springframework spring-jdbc 5.2.0.RELEASE

优点

spring是一个轻量级,非入侵式的框架。
控制反转(IOC),面相切面编程(AOP)
支持事务的处理

Ioc思想

有依赖就有耦合,伴随着工业级应用的规模越来越庞大,对象之间的依赖关系也越来越复杂,经常会出现对象之间的多重依赖性关系,因此,架构师和设计师对于系统的分析和设计,将面临更大的挑战。对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。

8561cb697d2046bc9d0b91c71fcca8fe.png

首先,由于引入了IOC容器,现在A要用到B不是通过直接在A中new对象了,而是需要让IOC容器帮你从B中拿,IOC容器拿到过后再通过依赖注入(DI)注入进A中,这整个过程不再是A主动创建B对象了,而是A在被动接受IOC容器给A注入的B,这个对象是IOC容器通过反射创建的,控制权移交到了IOC容器那里。也就是说,对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

这个IOC容器就是降低耦合度的关键所在

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创建对象,spring中称为beran
        初始:类型 变量名 =new 类型();
        id=变量名    class=new 的对象
        property 给属性设一个值
  -->
  
  <bean id="hello2" class="com.wzs.pojo.hello">
    <property name="str" value="Spring"/>
  </bean>
  
</beans>
public class MyTest {
    public static void main(String[] args) {
        //获取spring的上下文对象
        ApplicationContext context =  new ClassPathXmlApplicationContext("beans.xml");
        User user = (User) context.getBean("user");
        user.getStr();
    }
}

IOC创建对象的方式

使用无参构造方法。
假设使用有参构造方法。

1.下标

<bean id="user" class="com.wzs.pojo.User">
        <constructor-arg index="0" value="wzs"></constructor-arg>
    </bean>

2.类型

 <bean id="user" class="com.wzs.pojo.User">
        <constructor-arg type="java.lang.String" value="wzs"></constructor-arg>
    </bean>

3.参数名

<bean id="user" class="com.wzs.pojo.User">
  <constructor-arg name="as" value="wzs"></constructor-arg>
    </bean>

总结

在配置文件加载的时候,容器中管理的对象就已经初始化了。

什么是bean

Bean的中文含义是“豆子”,顾名思义JavaBean是一段Java小程序。JavaBean实际上是指一种特殊的Java类,它通常用来实现一些比较常用的简单功能,并可以很容易的被重用或者是插入其他应用程序中去。所有遵循一定编程原则的Java类都可以被称作JavaBean。

Spring配置

alais

<alias name="user" alias="user2"></alias>

bean

<!--
        id:bean是唯一的标识符,对象名
        class:bean对象对应的全限定名: 包名+类型
        name:也是别名,可以取多个别名,alias只能取一个
    -->
<bean id="user" class="com.wzs.pojo.hello" name="u1,u2">

</bean>

import

多人开发将分支包导入到一个总包

<import resource="beans1.xml"></import>
<import resource="beans2.xml"></import>
<import resource="beans3.xml"></import>
ApplicationContext context =  new ClassPathXmlApplicationContext("applicationContext.xml");

依赖注入

构造器注入

set注入(重点)

依赖:bean对象的创建依赖于容器。

注入:bean对象中的所有属性

<bean id="address" class="com.wzs.pojo.Address"></bean>
    <bean id="student" class="com.wzs.pojo.Student">
        <!--普通值注入,value-->
            <property name="name" value="韦智深"></property>
        <!--bean注入,ref,引用-->
        <property name="address" ref="address"/>
        <!--数组注入,ref-->
      
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
                <value>水浒传</value>
            </array>
        </property>
      
      
        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>看剧</value>
            </list>
        </property>
      
      
        <property name="card">
            <map>
                <entry key="身份证" value="1112331231"></entry>
                <entry key="手机号" value="1304811245"></entry>
            </map>
        </property>
      
      
        <property name="games">
            <set>
                <value>lol</value>
                <value>BOB</value>
            </set>
        </property>
      
      
        <property name="wife" >
            <null></null>
        </property>

        <property name="info">
            <props>
                <prop key="学号" >211134028</prop>
            </props>
        </property>
      
    </bean>

拓展方式注入(P)

需要导入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"
       
       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 id="user" class="com.wzs.pojo.user" p:age="18" p:name="韦智深"/>

</beans>

getBean的参数问题

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        
        user user1 = (user) context.getBean("user");
        
        System.out.println(user1.toString());
    }
}
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        user user1 = context.getBean("user", user.class);
        System.out.println(user1.toString());
    }
}

拓展方式注入(C)

有参构造器注入

<bean id="user" class="com.wzs.pojo.user" c:age="18"/>

bean的作用域

创建 bean 定义时,将创建一个配方来创建该 bean 定义所定义的类的实际实例。 bean 定义是配方的想法很重要,因为它意味着与类一样,您可以从一个配方中创建许多对象实例。

您不仅可以控制要插入到从特定 bean 定义创建的对象中的各种依赖项和配置值,还可以控制从特定 bean 定义创建的对象的范围。这种方法功能强大且灵活,因为您可以选择通过配置创建的对象的范围,而不必在 Java 类级别上烘烤对象的范围。可以将 Bean 定义为部署在多个范围之一中。 Spring 框架支持六个范围,其中只有在使用网络感知ApplicationContext时才可用。您也可以创建自定义范围。

image.png

如果使用默认的singleton,如果使用同一个id进行实例化对象时,多个对象的地址相同。

bean的自动装配

自动装配是Spring满足bean依赖一种方式!
Spring会在上下文中自动寻找,并自动给bean装配属性!

Spring三种装配的方式

  • xml中显示的配置
  • 在java中显示配置
  • 隐式的自动装配
<!--byName:会在容器的上下文寻找,和自己对象的set方法后边对应的bean id-->
    <bean id="person" class="com.wzs.pojo.person" autowire="byName">
        <property name="name" value="wzs"/>
    </bean>

满足后可自动装配。取代ref

<!--byType:会在容器上下文中查找,和自己对象属性类型相同的bean	-->
    <bean id="person" class="com.wzs.pojo.person" autowire="byType">
        <property name="name" value="wzs"/>
    </bean>

buName:保证bean的 id唯一,并且这个bean需要和自动注入的属性的set方法的值一致。
byType:保证bean的class唯一,并且这个bean需要和自动注入的属性的类型一致。

bean的生命周期

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

    <context:annotation-config/>

</beans>

@Autowired

:::info
如果出现NoSuchBeanDefinitionException错误,应首先检查是否出现值需要扫描的对象是否为组件,即是否加入了注解。
:::

public class person {
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;

}

@Autowired(required=false),假如已经定义好的Bean中找不到对应的类型,允许不注入,这样就没有了异常抛出。

  • 如果找到多个相同类型的组件,再根据属性的名称作为组件id去spring容器中找:annotationContext.getBean(“person”) 。
  • required:属性默认为true,表示自动注入的Bean必须能够找到,否则就会报null,设置为false,可以在Spring容器自动注入Bean找不到的话,返回null,不会报错。
  • @Autowired可以和@Qualifie注解使用,用来指定注入的组件id,而不是使用属性名。
  • @Autowired默认先按Type进行匹配,如果找到多个bean,则又会按照组件id方式进行匹配(需要@Qualifier(“name”)配合)。查找XML中的多个对象,默认使用第一个。制定一个装配的值。

@Resource

@Resource 注解和@Autowired注解作用比较相似,也是实现组件的自动注入。它是JAVA2EE提供的注解,使用的时候需要导入javax.annotation.Resourc 。

当没有id匹配,class都相同时,Resource就无法找到
@Resource默认按照组件id自动注入,如果按照默认组件id找不到bean时,再按照类型去匹配。

注入顺序

  • 同时指定了组件id和type,则从Spring上下文中找到唯一匹配的bean进行注入,找不到则抛出异常。
  • 指定了组件id,则从上下文中查找名称(id)匹配的bean进行注入,找不到则抛出异常。
  • 指定了type,则从上下文中找到类型匹配的唯一bean进行注入,如果找不到或者找到多个,都会抛出异常。
  • 既没有指定组件ide,又没有指定type,则自动按照组件id方式进行注入;找不到的话,则回退为一个原始类型进行匹配,如果匹配则自动注入。

@Autowired 和 @Resource区别

  • @Autowired属于Spring注解,@Resource 由JAVA2EE提供,需要导入包javax.annotation.Resource。

  • @Autowired默认按Type注入,组件id的方式需要与@Qualifier(“name”)配合使用;

  • @Resource同时支持Type和组件id方式注入,默认按组件id注入。

  • @Autowired只包含一个参数:required,标明是否开启自动注入,默认是true。

  • 而@Resource包含七个参数,最重要的两个参数是:name 和 type,用来指定注入的方式。

  • @Autowired可以作用在:构造器、方法、参数、成员变量和注解上,

  • @Resource可以作用在:类、成员变量和方法上。

使用注解开发

AOP的包必须导入包,引入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"
       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">
  <context:component-scan base-package="com.wzs.pojo"/>
    <context:annotation-config/>
</beans>

@Compoent

value注解代表这个类在Spring中的id,这相当于XML方式定义的Bean的id,也可以简写成,@Compoent(“role”),甚至直接写成@Component,不写的话IOC容器默认类名,但是以首字母小写的形式作为id,为其生成对象装配到容器中。

//等价于在bean里注册了
@Component
public class User {
    public String name="wzs";
}

等价于

<bean id="user" class="com.wzs.pojo.user"/>

@Value

@Component
public class User {
    @Value("weizhishen")//等价于<property name="name" value="weizhishen"/>
    public String name;
}

@Compoent衍生注解

dao【Repository】
service【Service】
controller【Controller】
都是代表将某个类注册到Spring容器中装配bean。

扫描组件

●context:include-filter子节点表示要包含的目标类

注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。即:通过将use-default-filters属性设置为false,禁用默认过滤器(这样就不会默认扫描包下全部类),然后扫描的就只是include-filter中的规则指定的组件了。

●context:exclude-filter子节点表示要排除在外的目标类,不需要禁用默认过滤器
名称皆为全类名。

<context:component-scan base-package="com.wzs.controller">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
<context:component-scan base-package="com.wzs.controller">

    <context:exclude-filter type="assignable" expression="com.wzs.controller.UserController"/>
    </context:component-scan>

一般用于spirng整合mybatis。

<context:component-scan base-package="com.wzs.controller">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

表示默认扫描所有包,即controller,mapper,service等等,默认为true,一般在spring.xml里面与exclude-filter搭配使用,达到不注入controller的效果(一般在springMVC.xml里配置扫描controller,在这里排除以避免重复扫描)。

:::info
在使用 use-default-filters 属性时要分清楚需要扫描哪些包,是不是需要使用默认的 Filter 进行扫描。
简单总结就是 use-default-filters=“false” 需要和 context:include-filter 一起使用,而不能和 context:exclude-filter 属性一起使用。
:::

注解加扫描配置的id

:::info
默认为类的小驼峰,即类名的首字母为小写的结果。
:::

@Controller("controller")
public class UserController {
}

AOP

image.png
:::info
Proxy使用的是反射包内的new方法。
参数:
ClassLoader loader:类加载器,指定加载动态生成的代理类的类加载器。
class[] interfaces:获取目标对象实现的所有接口的class对象的数组。
InvocationHandler h:设置代理类中的抽象方法如何重写
:::

非核心业务是横切关注点,即日志功能等,非核心业务

名词

:::info

  • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 …
  • 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
  • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
  • 目标(Target):被通知对象。
  • 代理(Proxy):向目标对象应用通知之后创建的对象。
  • 切入点(PointCut):切面通知 执行的 “地点”的定义。
  • 连接点(JointPoint):与切入点匹配的执行点。
    :::
    image.png

动态代理:JDK原生的实现方式,需要被代理的目标类必须是衔接口。因为这个技术要求代理对象和目标对象实现同样的结构。

cglib:通过继承被代理的目标类实现代理,所以不需要目标类实现接口。

AspectJ:本质上是静态代理,将代理逻辑“织入”被代理的目标类变异的到的字节码文件。所以最终的效果是动态的。weaver就是织入器。Spring只是借用了AspectJ中的注解。

:::info
AOP:切面类和目标类都需要交给IOC容器管理
切面类必须通过@Aspect注解标识为一个切面
在Spring的配置文件中设置<aop:aspectj-autoproxy />开启基于注解的AOP
:::

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值