Spring 学习

1.什么是spring

  • spring是一个开源框架,spring为简化企业级开发而生,使用spring可以使简单的java bean 实现以前只有EJG才能实现的功能
  • spring是一个IOC和AOP容器框架

2.spring的特点

  • 轻量级 spring是非侵入性的 - 基于spring应用的开发中的对象可以不依赖于spring的API
  • 依赖注入 DI
  • 面向切面编程 AOP
  • 容器 spring是一个容器,因为它包含和管理应用对象的生命周期
  • 框架 spring实现了使用简单的组件配置组合成一个复杂的应用,在spring中可以使用xml和java注解组合这些对象
  • 一站式 在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库

3 Spring容器

在Spring IOC 容器读取bean配置、创建bean之前,必须对他进行实例化,只有在容器实例化后,才能从IOC容器里获取bean实例并使用它 

3.1 spring提供了两种类型的IOC容器实现

  • BeanFactory: IOC容器的基本实现
  • ApplicationContext: 提供了更多的高级特性,是BeanFactory的子接口 

    BeanFactory是Spring框架的基础设施,面向Spring本身;ApplicationContext面向Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory

4 IOC

4.1 什么是IOC

IOC(Inversion of Controller)其思想是反转资源获取的方向,传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,适时得返回资源。Dog dog = new Dod();而使用了IOC之后,则是容器主动得将资源推送给他所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源,这种行为也被称为查找的被动方式。

4.2 什么是DI

DI(Dependency Injection)IOC的另一种表述方式:即组件以一些预定义好的方式(例如:setter方法),接受来自容器的资源注入,相对于IOC而言,这种表述更直接


5 Bean的配置方式

5.1 通过全类名(反射)

<bean id="person1" class="com.example.demo.bean.Person">
    <property name="name" value="dong"/>
    <property name="age" value="12"/>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

5.2 通过工厂方法(静态工厂方法&实例工厂方法)

调运静态工厂方法创建Bean是将对象创建的过程封装到静态方法中,当客户端需要对象时,只需要简单地调用静态方法,而不用关心创建对象的细节。 
要声明通过静态方法创建的Bean,需要在Bean的class属性里指定拥有该工厂的方法的类,同时在factory-method属性里指定工厂方法的名称。最后,使用constrctor-arg元素为该方法传递方法参数。

<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
    <constructor-arg value="yyyy-MM-dd hh:mm:ss"/>
</bean>
<bean id="date" factory-bean="simpleDateFormat" factory-method="parse">
    <constructor-arg value="2018-11-11 11:11:11"/>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5.3 FactoryBean

Spring中有两种类型的Bean,一种是普通Bean,一种是工厂Bean,即FactoryBean。 
工厂Bean和普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂Bean的getObject方法所返回的对象

public class PersonFactoryBean implements FactoryBean<Person>{
    // 返回对象
    @Override
    public Person getObject() throws Exception {
        Person person = new Person();
        person.setId(2);
        person.setName("zhu");
        person.setAge(20);
        return person;
    }
    //返回类型
    @Override
    public Class<?> getObjectType() {
        return Person.class;
    }
    //是否是单例
    @Override
    public boolean isSingleton() {
        return true;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

5.4 基于注解配置

Spring能够从classpath下自动扫描,侦测和实例化具有特定注解的Bean组件

<context:component-scan base-package="com.girhub.dge1992.bean"/>
  • 1
  • 1

特定组件包括:

  • @Component:基本注解,表示了一个受Spring管理的Bean组件
  • @Respository:标识持久层Bean组件
  • @Service:标识服务层Bean组件
  • @Controller:标识表现层Bean组件 

自动装配类型:

  • @Autowired:根据类型自动装配
  • @Resource:注解要求提供一个Bean名称的属性,若该属性为空,则自动采用标注处的变量和方法名作为Bean的名称
  • @Inject:和@Autowired很像,只是没有reqired属性 

对于扫描到的组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写,也可以在注解中通过value属性值标识组件的名称


6 依赖注入的方式

spring支持3种依赖注入的方式

6.1 属性注入

使用对象的set方法

<bean id="person1" class="com.github.dge1992.bean.Person">
    <property name="name" value="feng"/>
    <property name="age" value="3"/>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

6.2 构造器注入

使用对象的构造函数

<bean id="person2" class="com.github.dge1992.bean.Person">
        <constructor-arg value="dong" index="0" type="java.lang.String"></constructor-arg>
        <constructor-arg value="23" index="1" type="java.lang.Integer"></constructor-arg>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

6.3 工厂方法注入(很少使用不推荐)


7 注入属性值细节

7.1 字面值

可以用字符串表示的值,可以通过元素标签或value属性进行注入。 
基本数据类型及其封装类、String等类型都可以采用字面值注入的方式。

若字面值中包含特殊字符,可以通过<![CDATA[]]>把字面值包裹起来。
<bean id="car1" class="com.girhub.dge1992.bean.Car">
    <property name="name">
        <value type="java.lang.String"><![CDATA[<奔驰>]]></value>
    </property>
    <property name="type" value="高档车"/>
    <property name="price" value="1000"/>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

7.2 引用其他bean

组成应用程序的bean经常需要相互协助以完成应用程序的功能,要使bean能够互相访问,就必须在bean配置文件中指定对bean的引用。 
在bean的配置文件中,可以通过元素或ref属性为bean的属性或构造器参数指定对bean的引用。 
也可以在属性或构造器里包含bean的声明,这样的bean成为内部bean.

<bean id="car1" class="com.girhub.dge1992.bean.Car">
    <property name="name">
        <value type="java.lang.String"><![CDATA[<奔驰>]]></value>
    </property>
    <property name="type" value="高档车"/>
    <property name="price" value="1000"/>
</bean>
<bean id="person1" class="com.girhub.dge1992.bean.Person">
    <property name="name" value="feng"/>
    <property name="age" value="3"/>
    <property name="car" ref="car1"/>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

7.3 注入参数详解:null和级联属性

可以使用专用的元素标签为bean的字符串或其他对象类型的属性注入null值,spring支持级联属性的配置。

<bean id="person1" class="com.girhub.dge1992.bean.Person">
    <property name="name" value="feng"/>
    <property name="age" value="3"/>
    <property name="car" ref="car1"/>
    <property name="car.name" value="奔驰"/>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

7.4 集合属性

在spring中可以通过一组内置的xml标签(例如:,,)来配置集合属性。通过指定简单的常量值,通过指定对其他bean的引用,通过指定内置bean定义,通过指定空元素。 
java.util.Map通过标签定义,标签里可以使用多个作为子标签,普通常量使用key和value来定义,bean引用通过key-ref和value-ref属性定义。. 

使用utility scheme 定义集合 
使用p命名空间,简化xml文件的配置

<bean id="person1" class="com.girhub.dge1992.bean.Person">
    <property name="name" value="feng"/>
    <property name="age" value="3"/>
    <property name="cars">
        <list>
            <bean class="com.girhub.dge1992.bean.Car">
                <property name="name">
                    <value type="java.lang.String"><![CDATA[<奔驰>]]></value>
                </property>
                <property name="type" value="高档车"/>
                <property name="price" value="1000"/>
            </bean>
            <bean class="com.girhub.dge1992.bean.Car">
                <property name="name">
                    <value type="java.lang.String"><![CDATA[<奔驰111>]]></value>
                </property>
                <property name="type" value="高档车111"/>
                <property name="price" value="1000111"/>
            </bean>
        </list>
    </property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

集合引用外部bean

<bean id="person1" class="com.girhub.dge1992.bean.Person">
    <property name="name" value="feng"/>
    <property name="age" value="3"/>
    <property name="cars">
        <list>
            <ref bean="car1"/>
            <ref bean="car2"/>
        </list>
    </property>
    <property name="names">
        <list>
            <value>AAA</value>
            <value>BBB</value>
        </list>
    </property>
    <property name="carMap">
        <map>
            <entry key="first" value-ref="car1"/>
            <entry key="second" value-ref="car2"/>
        </map>
    </property>
    <property name="nameMap">
        <map>
            <entry key="firstName" value="CCC"/>
            <entry key="secondName" value="DDD"/>
        </map>
    </property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

8 自动装配

8.1 bean的自动装配(注解注入时用到)

Spring IOC 容器可以自动配置bean,需要做的仅仅是在的autowite属性里指定自动装配的模式

  • byType(根据类型自动装配)
  • byName(根据名称自动装配)

8.2 bean自动装配的缺点

在Bean配置文件里设置autowire属性进行自动装配将会装配bean的所有属性。然而,若只希望装配个别属性时,autowire属性就不灵活了。 

autowire属性要么根据类型自动装配,要么根据名称自动装配,不能两者一起使用。


9 bean之间的关系

9.1 继承

Spring允许继承bean的配置,被继承的bean成为父bean,继承这个bean的bean成为子bean,子bean从父bean中继承配置,也可以覆盖bean继承过来的配置。

<bean id="person1" class="com.girhub.dge1992.bean.Person" p:name="dong" p:car-ref="car1"/>
<bean id="person2" class="com.girhub.dge1992.bean.Person" parent="person1"/>
  • 1
  • 2
  • 1
  • 2

9.2 依赖

Spring允许用户通过 depends-on 属性设置 bean 前置依赖的bean,前置依赖的bean会在本bean实例化之前创建好。

<bean id="car1" class="com.girhub.dge1992.bean.Car">
    <property name="name" value="宝马"/>
</bean>
<bean id="person3" class="com.girhub.dge1992.bean.Person" depends-on="car1"/>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

10 bean的作用域

在Spring中,可以在元素的scope属性里设置bean的作用域。 
默认情况下,Spring只为每个在IOC容器里声明的Bean创建唯一一个实例,整个IOC容器范围内都能共享该实例:所有后续的getBean()调用和Bean引用都将返回这个唯一的Bean实例,该作用域被称为singleton,他是所有bean的默认作用域。

类别说明
singleton在Spring容器中仅存在一个bean实例,bean以单例是形式存在
prototype每次调用getBean(),都会返回一个新的实例
request每次HTTP请求都会创建一个新的实例,该作用域适用于WebApplicationContxt环境
session同一个HTTP Session共享一个Bean,不同的HTTP Session使用不同的Bean。该作用域只适合WebApplicationContxt环境

11 使用外部属性文件

11.1 使用外部属性文件的好处

完成属性值和bean的配置的分离,实现解耦

11.2 IOC容器如何引用外部文件

<context:property-placeholder location="文件路径">
  • 1
  • 1

11.3 如何引用外部属性文件的值

属性文件一般是 *.properties 数据以key=value的形式 通过${key}获取


12 Spring表达式语言:SpringEL

12.1 简介

Spring表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言

12.2 使用方法

使用#{…}作为定界符

12.3 SpEL的实现

  • 通过bean的id对bean进行引用
  • 调用方法以及引用对象中的属性
  • 计算表达式的值
  • 正则表达式的匹配 
    <bean id="car1" class="Car">
            <property name="name" value="宝马"/>
            <property name="price" value="10"/>
        </bean>
        <bean id="person1" class="Person">
            <property name="name" value="dong"/>
            <property name="car" value="#{car1}"/>
            <property name="age" value="10"/>
        </bean>
        <bean id="person2" class="Person">
            <property name="name" value="#{person1.name.toUpperCase()}"/>
            <property name="car" value="#{car1}"/>
            <property name="age" value="#{person1.age + 10}"/>
        </bean>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

13. bean的生命周期

Spring IOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务。在Bean的声明里设置init-method 和 destroy-method属性,为Bean设置初始化和销毁方法。 

Spring IOC容器对Bean的生命周期进行生命周期管理的过程:

  • 通过构造器或工厂方法创建Bean实例
  • 为Bean的属性设置值和对其他Bean的引用
  • (后置处理器前置方法执行)(可选)
  • 调用Bean的初始化方法
  • (后置处理器后置方法执行)(可选)
  • 可以使用Bean了
  • 当容器关闭时,调用Bean的销毁方法

13.1 Bean后置处理器

Bean后置处理器允许在调用初始化方法前后对Bena进行额外的处理。 

Bean后置处理器对IOC容器里的所有Bean实例逐一处理,而非单一实例,其典型作用是:检查Bean属性的正确性或根据特定的标准更改Bena的属性。 

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("后置处理器前置方法执行");
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("后置处理器后置方法执行");
        return bean;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

14. AOP

14.1 Java中的代理

代理是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象。这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。 

14.2 Java动态代理

public class CalculateProxy {
    //代理对象
    private Calculate calculate;
    public CalculateProxy(Calculate calculate) {
        this.calculate = calculate;
    }
    public Calculate getCalculateProxy(){
        ClassLoader classLoader = Calculate.class.getClassLoader();
        Class[] interfaces = {Calculate.class};
        InvocationHandler handler = new InvocationHandler() {
            /**
             *
             * @param proxy          代理的对象
             * @param method         被代理对象的方法
             * @param args           方法参数
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Arrays.stream(args).forEach(e -> System.out.println("参数是:" + e));
                //calculate是目标对象
                Object invoke = method.invoke(calculate, args);
                System.out.println("结果是:" + invoke);
                return invoke;
            }
        };
        /**
         * ClassLoader: 指定当前目标对象使用类加载器,获取加载器的方法是固定的
         *  Class<?>[]: 目标对象实现的接口的类型,使用泛型方式确认类型
         *  InvocationHandler h: 事件处理,执行目标对象的方法时,会触发事件处理器的方法,
         *                       会把当前执行目标对象的方法作为参数传入
         */
        Calculate calculate = (Calculate) Proxy.newProxyInstance(classLoader, interfaces, handler);
        return calculate;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37


14.3 Cglib动态代理

public class ProxyFactory implements MethodInterceptor {
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
    }
    public Object getProxyInstance(){
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("111");
        Object invoke = method.invoke(target, args);
        System.out.println("222");
        return invoke;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23


14.4 AOP简介

AOP(面向切面编程):是一种新的方法论,是对传统OOP(面向对象编程)的补充 
AOP的主要编程对象是切面,而切面模块化横切关注点 
在应用AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能在哪里。这样一来横切关注点就被模块化到特殊的对象里。 

14.5 AOP的好处

  • 每个事物逻辑位于一个位置,代码不分散,便于维护和升级
  • 业务模块更简洁,只包含核心业务代码 

14.6 AOP术语

名称简介
连接点程序运行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点,相对点表示的位置。
切点AOP通过切点定位到特殊的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。
切面横切关注点被模块化的特殊对象。
通知切面必须要完成的工作
目标被通知的对象
代理向目标对象应用通知之后创建的对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 内容概要 《计算机试卷1》是一份综合性的计算机基础和应用测试卷,涵盖了计算机硬件、软件、操作系统、网络、多媒体技术等多个领域的知识点。试卷包括单选题和操作应用两大类,单选题部分测试学生对计算机基础知识的掌握,操作应用部分则评估学生对计算机应用软件的实际操作能力。 ### 适用人群 本试卷适用于: - 计算机专业或信息技术相关专业的学生,用于课程学习或考试复习。 - 准备计算机等级考试或职业资格认证的人士,作为实战演练材料。 - 对计算机操作有兴趣的自学者,用于提升个人计算机应用技能。 - 计算机基础教育工作者,作为教学资源或出题参考。 ### 使用场景及目标 1. **学习评估**:作为学校或教育机构对学生计算机基础知识和应用技能的评估工具。 2. **自学测试**:供个人自学者检验自己对计算机知识的掌握程度和操作熟练度。 3. **职业发展**:帮助职场人士通过实际操作练习,提升计算机应用能力,增强工作竞争力。 4. **教学资源**:教师可以用于课堂教学,作为教学内容的补充或学生的课后练习。 5. **竞赛准备**:适合准备计算机相关竞赛的学生,作为强化训练和技能检测的材料。 试卷的目标是通过系统性的题目设计,帮助学生全面复习和巩固计算机基础知识,同时通过实际操作题目,提高学生解决实际问题的能力。通过本试卷的学习与练习,学生将能够更加深入地理解计算机的工作原理,掌握常用软件的使用方法,为未来的学术或职业生涯打下坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值