Spring笔记系列--1--基本内容与xml配置

此篇博客不做商业用途,仅用于记录学习笔记,很多代码出自别人的资料。

什么是Spring?

Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。 提供了展现层 SpringMVC和持久层 Spring JDBCTemplate以及业务层事务管理等众多的企业级应用技术,还能整 合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架

什么是IOC(控制反转)?

第一次看到IOC是在大内老A的一篇.net Core框架解析上看到的,我的理解是:IOC是一种框架设计思想,它定义了一个容器,将原本由程序做的一些操作放在容器中,交由框架来实现~

这样说可能有点抽象,举个简单的例子,我们在使用MVC框架的时候,它的流程是通过路由到指定的控制器,再通过控制器来激活相应的View视图。我们简单的剖析一下它的实现(大内老A的文章里有讲):

首先我需要加一个监听器来监听用户的请求(java有三大组件,监听器,拦截器,servlet,.net中不太确定,应该也差不多),然后需要定义一个控制器根据用户请求来找对应的视图,再一个视图解析器用来显示视图。当一个请求过来的时候,如果用程序来实现我们这个流程,需要先实例化控制器,再实例化视图,每一个请求我们都需要做这样的操作,那代码的冗余就会很大。我们将这一套的东西封装在一个容器中,由框架帮我们实现,就不需要我们自己来动手了,简化了很大的开发流程,这里其实有点像模板模式,但是有区别。

在Spring中,所有的类和方法,我们都可以把它加载到我们的Spring容器里面。由容器在运行的时候帮我们自动创建这些类或者方法的实例,再通过依赖注入的方式,将这些实例注入到需要他们的地方。这应该也是Spring框架重配置的原因之一吧。IOC的这一块比较抽象。

什么是依赖注入(DI)?

 

用简单的三层来说明一下:我们在开发中由数据访问层(DAO)连接数据库,业务逻辑层(service)调用数据访问层(DAO)完成逻辑,再由表现层(UI)调用业务逻辑层(service),我们在service层中使用dao层的方法的时候,需要在service中将dao层的数据实例化出来,而使用了IOC的思想之后,我们的dao层是由容器帮我们创建的,所以,我们不需要手动的去创建dao层了,但是容器帮我们的创建的这个dao数据在哪?怎么用就成了一个问题。我们思考一下可不可以在service定义一个字段来接收容器帮我们创建的dao的实例?这就是依赖注入!

依赖注入主要有两种实现方式:一种是无参构造的方式注入,一种是set方法的注入。这里不细说,后面慢慢讲~

什么是AOP?

AOP又叫面向切面编程,与他对应的应该是OOP(面向对象编程),我理解的OOP是将现实中的物体特性抽取成一个可以用某些属性表示的实体类,在程序中处理。而AOP是在OOP的基础上,对OOP的一种优化或者说扩展。

我在之前的博客中记录过AOP是通过代理模式实现的。举个例子理解一下,就像我要买手机,然后在远方有一个实体店的机子不错,但是太远了,这时候,有一个中间商跟我说,我能帮你搞到,但是你得多付钱,当然我会给你一些小赠品,我一听蛮合算的,就答应了。这个例子在程序中的一个表现就是,我要删除某个东西,在dao层有一个删除方法,后来,产品说要在删除之前加一个日志,我通过一个新的方法封装这个删除方法,然后在新方法的删除之前加一个日志方法,在表现层调用这个新方法。其中新方法类似于中间商,删除方法类似于远方的实体店,而日志,相当于小赠品,这里在删除方法之前加日志就叫做前置增强。其中删除的方法叫做切点,新方法叫切面,而封装新方法的过程叫做织入。

 Spring框架的基本使用(配置文件)

Bean标签基本配置:

用于配置对象交由Spring来创建,默认情况下是调用类中的无参构造函数,如果没有无参构造函数则不能创建成功。

基本属性:

id:Bean实例在Spring容器中的唯一标识

class:要配置对象的全限定名

scope:指对象的作用范围

    1.singleton:默认值,单例的,在Spring的核心配置文件加载的时候创建实例

    2.prototype:多例的,在使用getBean方法的时候加载。

使用Spring的API获取Bean的实例:

 

public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Spring核心配置文件名");
       UserDao userDao = (UserDao) applicationContext.getBean("配置文件中Bean的Id名");
       userDao.save();
}

通过Bean将类放入容器实例化的三种方法

1.使用无参构造实例化

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

2.工厂静态方法实例化

public class StaticFactoryBean {
   public static UserDao createUserDao(){
    return new UserDaoImpl();
} }
<bean id="userDao" class="com.itheima.factory.StaticFactoryBean" factory-method="createUserDao" />

在配置文件中的factory-method是你在这个类中要将哪一个方法添加到容器化里面实例化

3.工厂非静态方法实例化

<bean id="factoryBean" class="com.itheima.factory.DynamicFactoryBean"/>

<bean id="userDao" factory-bean="factoryBean" factory-method="createUserDao"/>

先将工厂类实例化出来,再将这个类中的方法实例化出来,factory-bean是实例化工厂Bean的id名

Bean的依赖注入

配置文件的方式注入(很少用,一般是用注解的方式注入)

   1.有参构造的注入方式

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/> 

<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>

constructor-arg是对有参构造的参数进行注入,name=是参数名,ref=是要注入的数据的Bean实例

  2.set方法注入

 

public class UserServiceImpl implements UserService {
   private UserDao userDao;
   public void setUserDao(UserDao userDao) {
       this.userDao = userDao;
}
   @Override
    public void save() {
        userDao.save();
} }

 

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>

property是对set方法进行注入,name是set方法去掉Set之后把第一个字母变小写的名字。ref是要注入的实例的id

Bean的依赖注入的数据类型

三种数据类型:普通数据,引用数据,集合数据。之前的都是引用数据的注入

  1.普通数据的注入

 

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

   <property name="age" value="15"></property>

</bean>

 

这是set方式的注入,普通数据用value来注入。

  2.集合数据的注入

  list:

list集合注入普通数据:

 

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

   <property name="strList">

       <list>

           <value>aaa</value>

           <value>bbb</value>

           <value>ccc</value>

       </list>

   </property>

</bean>

list集合注入引用类型数据

<bean id="u1" class="com.itheima.domain.User"/>
<bean id="u2" class="com.itheima.domain.User"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
   <property name="userList">
       <list>
           <bean class="com.itheima.domain.User"/>
           <bean class="com.itheima.domain.User"/>
           <ref bean="u1"/>
           <ref bean="u2"/>
      </list>
   </property>
</bean>

Map集合的注入

<bean id="u1" class="com.itheima.domain.User"/>

<bean id="u2" class="com.itheima.domain.User"/>

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

   <property name="userMap">

       <map>
             <entry key="user1" value-ref="u1"/>

            <entry key="user2" value-ref="u2"/>

       </map>

   </property>

</bean>

Properties(一般用于存储数据库连接信息)的注入

<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">

   <property name="properties">

       <props>

           <prop key="p1">aaa</prop>

           <prop key="p2">bbb</prop>

          <prop key="p3">ccc</prop>

       </props>

   </property>

</bean>

 AOP相关概念:

  Target(目标对象):代理的目标对象

  Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

  Joinpoint(连接点):所谓的连接点就是指那些可以被拦截到的点

  Pointcut(切入点:是指那些已经被拦截到的点

  Advice(通知/ 增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知

  Aspect(切面):是切入点和通知(引介)的结合

  Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入

AOP相关坐标

 

<!--导入spring的context坐标,context依赖aop-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.0.5.RELEASE</version>
</dependency>
<!-- aspectj的织入 -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.13</version>
</dependency>

配置文件:

<!--配置目标类-->
<bean id="target" class="com.itheima.aop.Target"></bean>
<!--配置切面类-->
<bean id="myAspect" class="com.itheima.aop.MyAspect"></bean>

在 applicationContext.xml 中配置织入关系:

<aop:config>
    <!--引用myAspect的Bean为切面对象-->
    <aop:aspect ref="myAspect">
        <!--配置Target的method方法执行时要进行myAspect的before方法前置增强-->
        <aop:before method="before" pointcut="execution(public void com.itheima.aop.Target.method())"></aop:before>
    </aop:aspect>
</aop:config>

 

posted @ 2020-03-20 09:59  码不够的张小墨  阅读(178)  评论(0编辑  收藏  举报