0306spring–IOC-AOP复习

  • Post author:
  • Post category:其他



一,spring是什么


Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的容器框架

理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架

优点:

弊端:违背了原有的技术理念:配置太过繁琐,被称为“配置地狱”

官方文档:core technologies


二,Spring框架由七个定义明确的模块组成

  • Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
  • Spring Core:核心类库,所有功能都依赖于该类库,提供IOC和DI服务;

  • Spring AOP:AOP服务;

  • Spring Web:提供了基本的面向Web的综合特性,提供对常见框架如Struts2的支持,Spring能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器;

  • Spring MVC:提供面向Web应用的Model-View-Controller,即MVC实现。

  • Spring DAO:对JDBC的抽象封装,简化了数据访问异常的处理,并能统一管理JDBC事务;

  • Spring ORM:对现有的ORM框架的支持;


三,现代化的开发就是基于spring容器的开发,


1.springboot :一个快速开发的脚手架

约定大于配置

2.springcloud:

springCloud是基于SpringBoot实现的


四,控制反转和面向切面


IOC:(获得依赖对象的方式反转了,对象由spring来创建,管理和装配)

1.控制反转:从本质上解决了问题,使我们程序员不用再去管理对象的创建了

系统的耦合性大大降低,可以更专注于业务的实现(IOC的原型)

1)以前:程序是需要程序员主动创建对象,控制权在开发人员手上

2)使用了set方法,程序不再具有主动性,而是变成了被动的接受对象,主动权在用户手上

3)配置:

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


ref: 引用Spring容器中创建好的对象

value:具体的值,基本数据类型

4)IOC创建对象的方法:

1.默认使用无参构造创建对象

2. 手动配置有参构造:constructor

1)下标赋值:index

2)通过类型创建(不建议)

3)通过参数名:name

5)在配置文件加载的时候,容器中管理的对象就已经初始化了,(容器类似于婚介所,只有对象注册到了婚介所,当容器applicationcontext被创建,被管理的对象也就存在,也就是被初始化了)


五,spring的配置


1.别名:

alias:—–>如果添加了别名,我们也可以通过别名获取对象

2.Bean的配置:

id:bean的唯一标识符,也就是相当于我们的对象名

class:bean的全限定名“包名+类名”(bean对象所对应的全限定名)

name: 也是别名:而且name比alias更高级,可以同时取多个别名(逗号或空格或分号分割)

ref:引用Spring容器中创建好的对象

value:具体的值,基本数据类型

3.import:

1)这个import,一般用于团队开发,可以将多个配置文件,导入合并为一个

2)假设项目中有多个人开发,这三个人负责不同类的开发,不同类需要注册到不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的

张三:beans

李四:beans2

王五:beans3

applicationContext.xml:

<import resource=”beans.xml”/>

<import resource=”beans2.xml”/>

<import resource=”beans3.xml”/>

使用的时候,直接使用总的配置就好了


六,DI依赖注入


1.构造器注入:

2.通过set方式注入

依赖注入:set注入

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

注入:bean对象中的所有属性,由容器来注入

环境搭建:

1.复杂类型

2.真实测试对象

<bean id="student" class="com.kuang.pojo.Student">
        <!--第一种,普通注入-->
        <property name="name" value="小俊"/>
        <!--第二种:bean注入,ref-->
        <property name="address" ref="address"/>
        <!--第三种:,数组注入-->
        <property name="books">
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
        </property>
        <!--第四种:list-->
        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>王者</value>
                <value>跳舞</value>
            </list>
        </property>
        <!--第五种:map-->
        <property name="card">
            <map>
                <entry key="身份证" value="1234543234543234"/>
                <entry key="银行卡" value="3ueqrqyrqoyrqywqo"/>
            </map>
        </property>
        <!--第六种:set-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>COC</value>
                <value>BoB</value>
            </set>
        </property>
        <!--第七种:null-->
        <property name="wife">
            <null/>
        </property>
        <!--第八种:properties-->
        <property name="info">
            <props>
                <prop key="学号">190970070</prop>
                <prop key="性别">男</prop>
                <prop key="姓名">小俊</prop>
            </props>
        </property>
    </bean>


3.其他方式注入

注意:这两种不能直接使用,需要去导入约束,从官方文档去拿

1)p命名注入       xmlns:p=”http://www.springframework.org/schema/p”

2)c命名注入      xmlns:c=”http://www.springframework.org/schema/c”

<!–p命名空间,可以直接注入属性的值–>

<bean id=”user” class=”com.kuang.pojo.User” p:name=”小俊” p:age=”18″/>

<!–c命名空间,通过构造器注入:construct-args–>

<bean id=”user2″ class=”com.kuang.pojo.User” c:age=”18″ c:name=”小俊俊”/>

4.bean的作用域:

1)单例模式:singleton:

spring 默认机制

<bean id=”user2″ class=”com.kuang.pojo.User” c:age=”18″ c:name=” 小俊俊”  scope=”singleton”/>

2)原型模式:prototype:

每次从容器中get的时候,都会产生一个新对象

3)其他的在web中才用到


七.Bean的自动装配

自动装配是spring满足bean依赖的一种方式

spring会在上下文中自动寻找,并自动给bean装配属性

三种装配在方式:

1)在xml中显示的配置

2)在java中显示的配置


3)隐式的自动装配bean(重要)



1.byName自动装配


byName会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanID

<bean id="people" class="com.kuang.pojo.People" autowire="byName">
        <property name="name" value="小俊俊呀!"/>
    </bean>



2.byType自动装配


byName会自动在容器上下文中查找,和自己对象属性类型相同的beanID

<bean id="people" class="com.kuang.pojo.People" autowire="byType">
        <property name="name" value="小俊俊呀!"/>
    </bean>


3.小结:

  • byname的时候:需要保证所有bean的

    id唯一

    ,并且这个bean需要和自动注入的

    属性的set方法值一致
  • byname的时候:需要保证所有bean的

    class唯一

    ,并且这个bean需要和自动注入的

    属性的类型值一致


4)  使用注解实现自动配置:


The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.


要使用注解须知:

1.导入上下文约束

2.导入约束(context约束):<context:annotation-config/>

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

    <context:annotation-config/>

</beans>


3.@Autowired:


1)直接在属性上使用即可,也可以在set方式上使用

使用autowired,我们可以不用编写set方法了,前提是你这个自动装配的实行在IOC容器中 已 经存在了,并且名字符合byName!

2)科普:

1,

@Nullable

:字段如果标记了这个注解,那说明这个字段可以为空

2,@Qualifier:如果自动装配环境比较复杂,自动装配无法通过一个注解完成的时候,我们可以使用@Qualifier(value=”xxx”)去配合@Autowired使用,指定一个唯一的bean对象注入


4,@Resource:

@Resource:(name=”cat”)


5,@Resource和@Autowired区别:


1).都是用来自动装配的,都可以放到属性字段上

2)@Autowired通过byname的方式实现,而且必须要求这个对象存在

3)@Resource默认通过byname方式实现没如果找不到名字,则通过byType,,如果两个都找不到,就会报错(也可以通过name去指定)


八.使用注解开发


  • 在spring4之后,如果要使用注解开发,必须要保证aop的包已经导入了


  • 使用注解需要导入context约束,增加注解支持

1.bean注入:@Component

2.属性注入:@Value

3.衍生的注解:

  • Component有几个衍生的注解,在web开发中,会按照MVC三层架构分层
  • dao:【@Repository】
  • service:【@Service】
  • controller:【@Controller】
  • 这四个注解的功能都是一样的,都是代表将某个类注册到spring容器中,装配

4.自动装配

  • @Autowired:
  • @Nullable:
  • @Resource:

5.作用域:

@Scope:指定模式:单例(singleton),原型(prototype)

6.小结

  1. xml与注解:

    1. xml更加万能,适用于任何场合,维护更加简单
    2. 注解不是自己的类使用不了,维护相对复杂
  2. xml与注解最佳实践

    1. xml用来管理bean:
    2. 注解只负责完成属性的注入
    3. 我们在使用的过程中,只需要注意一个问题:

      必须让注解生效,就必须要开启注解支持


​九,完全使用java的方式配置spring(新特性)


我们现在要完全不使用spring的xml配置了,全权交给java来做

javaConfig是spring的一个子项目



这种纯java的配置方式,在springboot中随处可见

  • 实体类:

    • package com.kuang.pojo;
      
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Component;
      import org.springframework.stereotype.Controller;
      @Component//这个注解表示这个对象呗spring接管了
      public class User {
          private String name;
      
          public String getName() {
              return name;
          }
          @Value("小俊")//属性注入值
          public void setName(String name) {
              this.name = name;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      '}';
          }
      }
      
  • 配置类:

    • package com.kuang.config;
      
      import com.kuang.pojo.User;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration//这个也会被spring容器托管,因为他本身就是一个组件,这个注解代表是一个配置类,就和我们之前看到的beans.xml是一样的
      public class KuangConfig {
          //注册一个bean,就相当于我们写的一个bean标签
          //这个方法的名字,就相当于bean标签中的id属性
          //这个方法的返回值,就相当于bean标签中的class属性
          @Bean
          public User getUser() {
              return new User();//就是返回要注入到bean的对象
          }
      }
      
  • 测试类:

    • import com.kuang.config.KuangConfig;
      import com.kuang.pojo.User;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      
      public class MyTest {
          public static void main(String[] args) {
              //如果完全使用了配置类方式去做,我们就只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象来加载
              ApplicationContext context = new AnnotationConfigApplicationContext(KuangConfig.class);
              User getUser = (User) context.getBean("getUser");
              System.out.println(getUser.getName());
          }
      }
      


十,代理模式:

为什么要学代理模式?因为这就是SpringAOP的底层!(SpringAOP和SpringMVC)

代理模式分类:


1)静态代理

  • 角色分析:

    • 抽象角色:一般会用接口或者抽象类来解决
    • 真实角色:被代理的角色
    • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
    • 客户:访问代理对象的人
  • 代码步骤:

    • 接口:
    • //租房
      public interface Rent {
          public void rent();
      }
      
    • 真实角色:
    • //房东
      public class RentHostImpl implements Rent {
          @Override
          public void rent() {
              System.out.println("房东要出租房子!");
          }
      }
    • 代理角色:
    • //中介
      public class RentProxyImpl implements Rent {
          private RentHostImpl rentHost;
          public RentProxyImpl() {
          }
          public RentProxyImpl(RentHostImpl rentHost) {
              this.rentHost = rentHost;
          }
          @Override
          public void rent() {
              rentHost.rent();
              seeHouse();
              heTong();
              fare();
          }
          //看房
          public void seeHouse() {
              System.out.println("中介带你看房");
          }
          //签合同
          public void heTong() {
              System.out.println("签租赁合同");
          }
          //收中介费
          public void fare() {
              System.out.println("收中介费");
          }
      }
    • 客户端访问代理角色:
    • //客户
      public class Client {
          public static void main(String[] args) {
              RentHostImpl rentHost = new RentHostImpl();
              rentHost.rent();
              //代理
              RentProxyImpl rentProxy = new RentProxyImpl(rentHost);
              rentProxy.rent();
          }
      }
  • 代理模式的好处:

    • 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
    • 公共也就是交给代理角色,实现了业务的分工
    • 公共业务发生扩展的时候,方便集中管理
  • 缺点:

    • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低


2)动态代理(为了改变静态代理的缺点)

  • 动态代理和静态代理角色一样
  • 动态代理是动态生成的,不是我们直接写好的
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理


    • 基于接口:jdk动态代理

    • 基于类:cglib

    • java字节码实现:javasist

  • 需要了解两个类::Proxy代理,  InvocationHandler调用处理程序

  • 动态代理的好处:

    • 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务
    • 公共也就是交给代理角色,实现了业务的分工
    • 公共业务发生扩展的时候,方便集中管理

    • 一个动态代理类代理的是一个接口,一般就是对应一类业务

    • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可(rent接口,rent接口的两个实现类,只需要写一个动态代理类)


十一,什么是AOP


1)


2)


3)使用spring实现AOP


  • 【重点】:使用aop织入,需要导入一个依赖包
  •     <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.9.6</version>
            </dependency>
        </dependencies>
  • 方式一:使用spring的api接口
  • 方式二:使用自定义类来实现AOP



版权声明:本文为qq_60555957原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。