zoukankan      html  css  js  c++  java
  • spring01

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

    Spring的核心jar包

      spring-framework-3.2.0.RELEASE-dist.zip    -------Spring的核心包
      spring-framework-3.0.2.RELEASE-dependencies.zip  ------ Spring的依赖包

    spring-core-3.2.2.RELEASE.jar:

    包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心

    spring-beans-3.2.2.RELEASE.jar:

    包含访问配置文件、创建和管理bean

    以及进行Inversion of Control(IoC) / Dependency Injection(DI)操作相关的所有类

    spring-expression-3.2.2.RELEASE.jar

    Spring表达式语言
     

    spring-context-3.2.2.RELEASE.jar

    Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,

    如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等
     

    com.springsource.org.apache.commons.logging-1.1.1.jar

    第三方的主要用于处理日志

    IOC&&DI

    IOC控制反转的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理,即创建对象控制权被反转到了Spring框架

    DI 依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件

    BeanFactory && ApplicationContext

    BeanFactory 才是 Spring 容器中的顶层接口。
    ApplicationContext 是它的子接口。

    区别:

      ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
      BeanFactory:什么使用什么时候创建对象

    bean标签

    作用:
      用于配置对象让 spring 来创建的。
      默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
    属性:
      id: 给对象在容器中提供一个唯一标识。用于获取对象。
      class: 指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
      scope: 指定对象的作用范围。
        * singleton :默认值,单例的.
        * prototype :多例的.
        * request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
        * session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
        * global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么
    globalSession 相当于 session.
        init-method: 指定类中的初始化方法名称。
        destroy-method: 指定类中销毁方法名称。

    实例化bean的三种方式

    使用构造方法实例化

    1 使用默认无参构造函数
    2 
    3 根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败
    4 
    5 <bean id="accountService" class="com.xxx.service.impl.AccountServiceImpl"/>

    使用静态工厂实例化

     1 /**
     2 * 模拟一个静态工厂,创建业务层实现类
     3 */
     4 public class StaticFactory {
     5 public static IAccountService createAccountService(){
     6 return new AccountServiceImpl();
     7   }
     8 }
     9 
    10 <!-- 此种方式是:
    11     使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器
    12     id 属性:指定 bean 的 id,用于从容器中获取
    13     class 属性:指定静态工厂的全限定类名
    14     factory-method 属性:指定生产对象的静态方法
    15 -->
    16 <bean id="accountService"
    17 class="com.xxx.factory.StaticFactory"
    18 factory-method="createAccountService"></bean>

    使用实例工厂方法实例化

     1 /**
     2 * 模拟一个实例工厂,创建业务层实现类
     3 * 此工厂创建对象,必须现有工厂实例对象,再调用方法
     4 */
     5 public class InstanceFactory {
     6 public IAccountService createAccountService(){
     7     return new AccountServiceImpl();
     8     }
     9 }
    10 <!-- 此种方式是:
    11     先把工厂的创建交给 spring 来管理。
    12     然后在使用工厂的 bean 来调用里面的方法
    13         factory-bean 属性:用于指定实例工厂 bean 的 id。
    14         factory-method 属性:用于指定实例工厂中创建对象的方法。
    15 -->
    16 <bean id="instancFactory"         
    17         class="com.xxx.factory.InstanceFactory"></bean>
    18     <bean id="accountService"
    19 factory-bean="instancFactory"
    20 factory-method="createAccountService"></bean>

    Spring依赖注入方式

    构造函数注入

     1 public class AccountServiceImpl implements IAccountService {
     2   private String name;
     3   private Integer age;
     4   private Date birthday;
     5 public AccountServiceImpl(String name, Integer age, Date birthday) {
     6   this.name = name;
     7   this.age = age;
     8   this.birthday = birthday;
     9 }
    10 //
    11 
    12 }
    13 
    14 
    15 <!--
    16 
    17 constructor-arg
    18 属性:
    19     index:指定参数在构造函数参数列表的索引位置
    20     type:指定参数在构造函数中的数据类型
    21     name:指定参数在构造函数中的名称
    22     value:它能赋的值是基本数据类型和 String 类型
    23     ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
    24 -->
    25 
    26 <bean id="accountService" class="com.xxx.service.impl.AccountServiceImpl">
    27 <constructor-arg name="name" value="张三"></constructor-arg>
    28 <constructor-arg name="age" value="18"></constructor-arg>
    29 <constructor-arg name="birthday" ref="now"></constructor-arg>
    30 </bean>
    31 <bean id="now" class="java.util.Date"></bean>

    Set方法注入‘

     1 public class User {
     2     private String username;
     3     private String password;
    4 public String getUsername() { 5 return username; 6 } 7 public void setUsername(String username) { 9 this.username = username; 10 } 11 public String getPassword() { 12 return password; 13 } 14 public void setPassword(String password) { 15 this.password = password; 16 } 17 18 19 } 20 <!----
    name:找的是类中 set 方法后面的部分
    ref:给属性赋值是其他 bean 类型的
    value:给属性赋值是基本数据类型和 string 类型的

    ----> 21 22 23 24 <bean id = "user" class= "com.xxx.model.User"> 25 <property name="username" value="gyf"></property> 26 <property name="password" value="123"></property> 27 28 </bean>

    集合注入

    也是set的注入方式

    集合的注入都是给<property>添加子标签

                       数组:<array>

                       List:<list>

                       Set:<set>

                       Map:<map> ,map存放k/v 键值对,使用<entry>描述

                       Properties:<props>  <prop key=""></prop>  【】           

    普通数据:<value>

    引用数据:<r 1 public class Programmer {

     2     
     3     private List<String> cars;
     4     
     5     private Set<String> pats;
     6 
     7     private Map<String,String> infos; 
     8     
     9     private Properties mysqlInfos;
    10     
    11     private String[] members;
    12       //setter getter
    13     
    14 }
    15 
    <!-- 注入集合数据
            List 结构的:
            array,list,set
            Map 结构的
            map,entry,props,prop
        -->
    16 <bean id="programmer" class="com.xxx.model.Programmer"> 17 <property name="cars"> 18 <!-- list数据的注入 --> 19 <list> 20 <value>offo</value> 21 <value>mobai</value> 22 </list> 23 </property> 24 25 26 <property name="pats"> 27 <set> 28 <value>猫</value> 29 <value>狗</value> 30 </set> 31 </property> 32 33 <!-- Map数据的注入 --> 34 <property name="infos"> 35 <map> 36 <entry key="name" value="gyf"></entry> 37 <entry key="age" value="12"></entry> 38 <entry key="ip" value="127.0.0.1"></entry> 39 </map> 40 </property> 41 42 43 <!-- Properties属性注入 --> 44 <property name="mysqlInfos"> 45 <props> 46 <prop key="url">mysql:jdbc://localhost:3306/dbname</prop> 47 <prop key="user">root</prop> 48 <prop key="password">root</prop> 49 </props> 50 </property> 51 52 53 54 55 <!-- 数组参数注入 --> 56 <property name="members"> 57 <array> 58 <value>哥哥</value> 59 <value>弟弟</value> 60 <value>妹妹</value> 61 </array> 62 </property> 63 64 65 </bean>

    注解注入

    注解:就是一个类,使用@注解名称

    开发中:使用注解 取代 xml配置文件。

     1 @Component
     2 @component取代<bean class="">
     3 
     4 
     5 @Component("id") 取代 <bean id="" class="">
     6 
     7 
     8 @Repository(“”):dao层
     9 @Service(“”):service层
    10 @Controller(“”):web层
    11 
    12 @Autowired:自动根据类型注入      @Qualifier(“”):指定自动注入的id名称
    13 @Resource(“名称”)
    14 
    15 @ PostConstruct 自定义初始化
    16 @ PreDestroy 自定义销毁

    Aop

    面向切面编程。

     作用:
    在程序运行期间,不修改源码对已有方法进行增强。

    优势:
    减少重复代码
    提高开发效率
    维护方便

    术语

    target:目标类,需要被代理的类。例如:UserService
    Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
    PointCut 切入点:已经被增强的连接点。例如:addUser()
    advice 通知/增强,增强代码。例如:after、before
    Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.
    proxy 代理类
    Aspect(切面): 是切入点pointcut和通知advice的结合 一个线是一个特殊的面。 一个切入点和一个通知,组成成一个特殊的面。

    jdk动态代理&&cglib动态代理

    基于接口的动态代理

    提供者: JDK 官方的 Proxy 类。
    要求:被代理类最少实现一个接口。

    基于子类的动态代理

    提供者:第三方的 CGLib,如果报 asmxxxx 异常,需要导入 asm.jar
    要求:被代理类不能用 final
    修饰的类(最终类)。

    通知

    前置通知 org.springframework.aop.MethodBeforeAdvice

             •在目标方法执行前实施增强

    后置通知 org.springframework.aop.AfterReturningAdvice

             •在目标方法执行后实施增强

    环绕通知 org.aopalliance.intercept.MethodInterceptor

             •在目标方法执行前后实施增强

     •异常抛出通知 org.springframework.aop.ThrowsAdvice

             •在方法抛出异常后实施增强

    引介通知 org.springframework.aop.IntroductionInterceptor

             在目标类中添加一些新的方法和属性

    1 环绕通知,必须手动执行目标方法
    2 
    3 try{
    4    //前置通知
    5    //执行目标方法
    6    //后置通知
    7 } catch(){
    8    //抛出异常通知
    9 }

    Aop配置

     1 IAccountService
     2 
     3 AccountServiceImpl
     4 
     5  <!-- 配置srping的Ioc,把service对象配置进来-->
     6     <bean id="accountService" class="com.xxx.service.impl.AccountServiceImpl"></bean>
     7 
     8 
     9 <!--spring中基于XML的AOP配置步骤
    10         1、把通知Bean也交给spring来管理
    11         2、使用aop:config标签表明开始AOP的配置
    12         3、使用aop:aspect标签表明配置切面
    13                 id属性:是给切面提供一个唯一标识
    14                 ref属性:是指定通知类bean的Id。
    15         4、在aop:aspect标签的内部使用对应标签来配置通知的类型
    16                我们现在示例是让printLog方法在切入点方法执行之前之前:所以是前置通知
    17                aop:before:表示配置前置通知
    18                     method属性:用于指定Logger类中哪个方法是前置通知
    19                     pointcut属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强 -->
    20     <!-- 配置Logger类,切面类 -->
    21     <bean id="logger" class="com.itheima.utils.Logger"></bean>
    22 
    23     <!--配置AOP-->
    24     <aop:config>
    25         <!--配置切面 -->
    26         <aop:aspect id="logAdvice" ref="logger">
    27             <!-- 配置通知的类型,并且建立通知方法和切入点方法的关联-->
    28             <aop:before method="printLog" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:before>
    29         </aop:aspect>
    30     </aop:config>

     切入点表达式的写法:

     关键字:execution(表达式)

    表达式:

    访问修饰符 返回值 包名.包名.包名...类名.方法名(参数列表)

    public void com.xxx.service.impl.AccountServiceImpl.saveAccount()

    访问修饰符可以省略    void com.xxx.service.impl.AccountServiceImpl.saveAccount()

    返回值可以使用通配符   ,表示任意返回值

    包名可以使用通配符,表示任意包。但是有几级包,就需要写几个*.

    *    * .* .*. *. AccountServiceImpl.saveAccount())

    包名可以使用..表示当前包及其子包
     *  *. . AccountServiceImpl.saveAccount()

    类名和方法名都可以使用*来实现通配
    *  *. . * . * ()

    参数列表:
    可以直接写数据类型:
      基本类型直接写名称 int
      引用类型写包名.类名的方式 java.lang.String
          可以使用通配符表示任意类型,但是必须有参数
             可以使用 . .  表示有无参数均可,有参数可以是任意类型

             ()                                                     无参

             (int)                                                一个整型

             (int ,int)                                         两个

             (..)                                                   参数任意


    全通配写法:

     * *. .*.*(. .)

    通常写法:切到业务层实现类下的所有方法
    * com.xxx.service.impl.*.*(..)

    基于注解的aop

    bean.xml

    1     <!-- 配置spring创建容器时要扫描的包-->
    2     <context:component-scan base-package="com.xxx"></context:component-scan>
    3 
    4     <!-- 配置spring开启注解AOP的支持 -->
    5     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    替换service和切面bean

    @Service

    @Component

    @Aspect//表明当前类是一个切面类

    在增强的方法上使用注解配置通知

    @Before
    作用:
    把当前方法看成是前置通知。
    属性:
     value:用于指定切入点表达式,还可以指定切入点表达式的引用。

          @Before("execution(* com.xxx.service.impl.*.*(..))")

    @AfterReturning 把当前方法看成是后置通知。

    @Around :把当前方法看成是环绕通知

    @Pointcut  指定切入点表达式

     1 @Aspect  声明切面,修饰切面类,从而获得 通知。
     2 
     3 @Before 前置
     4 
     5          @AfterReturning 后置
     6 
     7          @Around 环绕
     8 
     9          @AfterThrowing 抛出异常
    10 
    11          @After 最终
    12 
    13 切入点 @PointCut ,修饰方法 private void xxx(){}  之后通过“方法名”获得切入点引用

  • 相关阅读:
    git 删除远程文件、文件夹
    pod install太慢 可以使用代理的方式
    flutter Container()最小宽度 最小高度
    flutter common init 常用Widget初始化
    xcode 嵌入flutter_module后编译报错 This app could not be installed at this time.
    Spring AOP
    Spring @Value 配置项解析 vs Spring @ConfigurationProperties 配置项解析
    Spring Bean 的实例化过程
    SpringBoot 配置项解析
    Spring IOC 自动注入流程
  • 原文地址:https://www.cnblogs.com/quyangyang/p/11870180.html
Copyright © 2011-2022 走看看