Spirng+In+Action(Craig Walls Ryan Breidenbach)

2023-11-29 11:38

本文主要是介绍Spirng+In+Action(Craig Walls Ryan Breidenbach),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spirng+In+Action(Craig Walls Ryan Breidenbach)

目录

  1.开始Spring之旅(简介)

  2.装配Bean(IoC)

  3.创建切面(AOP)

  。。。

第一章:开始Spring之旅

  1.1 为什么使用Spring:简化了企业级系统开发。

    1.1.1 javaEE开发者的一天:EJB功能强大,即使简单的应用系统都需要各种组件的支持,使用较为复杂。

    1.1.2 Spring的承诺:

      1.好的设计比实现技术更重要

      2.通过接口松散耦合的JavaBean是一个很好的模型

      3.代码应该容易被测试

  1.2 Spring是什么:Spring是一个轻量级的IOC和AOP容器框架

    轻量级:1MB多的jar包源代码

    非侵入式:基于Spring开发系统中的对象一般不依赖于Spring框架中的类

    反向控制:创建一个对象时,需要在容器系统中寻找所对应的类,而反向控制,则是在容器启动实例化时,主动为引用的实例类注入依赖类对象

    面向切面:提取多种业务的共性,形成一种过滤效果,使开发者只需要关注具体的逻辑业务问题

    容器:可以管理系统中对象的生命周期与设置(BeanFactory/ApplicationContext)

    框架:通过XML文件配置组合

    spring组成模块:

      

  1.3 开始Spring之旅

//接口定义
package com.cys.test;public interface GreetingService {public void sayGreeting();
}
复制代码
//具体实现类
package com.cys.test;public class GreetingServiceImpl implements GreetingService {private String greeting;public GreetingServiceImpl() {}public GreetingServiceImpl(String greeting) {this.greeting = greeting;}public void sayGreeting() {System.out.println("GreetingServiceImpl [greeting=" + greeting + "]");        }public void setGreeting(String greeting) {this.greeting = greeting;}
}
复制代码
复制代码
//主函数类
package com.cys.test;import java.io.FileInputStream;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;public class HelloApp{public static void main(String[] args) throws Exception{BeanFactory factory = new XmlBeanFactory(new FileInputStream("spring-beans.xml"));GreetingService greeting = (GreetingService)factory.getBean("greetingService");greeting.sayGreeting();}
}
复制代码
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!-- xml配置文件 -->
<beans> <!-- 无参数构造 --><bean id="greetingService" class="com.cys.test.GreetingServiceImpl"><property name="greeting" value="Hello World" /></bean><!-- 带参数构造 --><bean id="greetingService" class="com.cys.test.GreetingServiceImpl"><constructor-arg><value>Hello World</value></constructor-arg></bean>
</beans> 
复制代码

  1.4 理解反向控制(依赖注入):获得依赖对象的方式反转

  1.5 应用AOP:IoC使软件组件松散连接成为可能,AOP让你能够捕捉经常使用的功能,把该功能转化为组件

    

  1.6 Spring比较

    

   小结:

  

  

第二章:装配Bean

  2.1 容器是Spring框架的核心:BeanFactory、ApplicationFactory

    2.1.1 BeanFactory:Bean简单工厂管理模式

      常见实现类:XmlBeanFactory

        BeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml"));

        MyBean myBean = factory.getBean("myBeanId");

    2.1.2 ApplicationFactory:提供更多附加的功能(文本信息解析工具、载入文件资源、注册监听器)

      常见实现类:ClassPathXmlApplicationFactory、FileSystemXmlApplicationFactory、XmlWebApplicationFactory

        ApplicationFactory factory = new ClassPathXmlApplicationFactory("beans.xml");

        ApplicationFactory factory = new FileSystemXmlApplicationFactory("c:/beans.xml");

        XmlWebApplicationFactory:见第八章

    2.1.3 Bean生命周期

  

    Bean工厂容器与ApplicationContext容器的唯一区别:ApplicationContext容器会调用ApplicationContextAware接口的setApplicationContext()方法

  2.2 基本配置(Beans.xml)

    2.2.1 xml配置:<beans><bean id="" class=""/><beans ...></beans>

    2.2.2 添加一个Bean

      bean属性:

        单实例与原型:singleton="true"--单实例(默认)  singleton="false"--原型(每次getBean(),获取的对象都是一个新的)

        实例化与销毁:init-method="name1"--初始化时调用name1()方法  destroy-method="name2"--销毁时调用name1()方法

    2.2.3 set属性注入

      基本类型注入(int、String、...):<property name="xxx"><value>xxx(值)</value></property>

      引入其他bean:<property name="xxx"><ref bean="xxx(beanId)"></property>(常用)、<property name="xxx"><bean class="" /></property>(不常用)

      List与数组:<property name="xxx"><list><value>xxx(值)</value><ref ...><...></list></property>(值可以是任意元素)

      Set:<property name="xxx"><set><value>xxx(值)</value><ref ...><...></set></property>(值可以是任意元素)

      Map:<property name="xxx"><map><entry key="xxx1"><value>xxx(值)</value></entry><entry key="xxx2"><ref ...></entry><entry key="..."><...></entry></map></property>(值可以是任意元素)

      Property:<property name="xxx"><prop key="xxx1">xxx(值)</prop><prop key="xxx2">xxx(值)</prop>...</property>(值只能是String类型,不需要<value>标签)

      设置null:<property name="xxx"><null/></property>(默认可以不设置,这是显示装配)

    2.2.4 构造函数注入

      与set同理,<property>改为<constructor-arg>,并提供了index、tyep属性

      index:参数序号,从0开始--<constructor-arg index="0"><value><ref ...>...</constructor-arg>  

      type:属性类型(java.lang.String)--<constructor-arg type="java.lang.String"><value><ref ...>...</constructor-arg>

      默认情况可以不设置,在多个参数类型相同时,为区分参数先后顺序,必须设置index属性

      set注入与构造函数注入区别:构造函数可以强制关联依赖关系,达到初始化一个完整可用的对象

  2.3 自动装配Bean(一般不考虑)

    。。。

  2.4 特殊bean:实现spring特定的接口,在bean生命周期的过程中处理bean信息

    2.4.1 对bean进行后处理:实例化后初始化前--初始化后

      接口:BeanPostProcessor

        覆盖方法(实例化后初始化前方法):postProcessBeforeInitialization(Object bean, String name)

        覆盖方法(初始化后方法):postProcessAfterInitialization

      注册bean:

        Bean工厂容器:factory.addBeanPostProcssor(BeanPostProcessor接口类的实现类)

        上下文容器:在xml配置文件里添加实现BeanPostProcessor接口的类bean即可,上下文容器会自动识别:<bean id="" class="" />

      spring框架自动BeanPostProcessor实现

        。。。

    2.4.2 对Bean工厂进行后处理:实例化之前,即容器加载bean配置文件定义,开始实例化每个bean之前

      接口:BeanFactoryPostProcessor

        覆盖方法(实例化之前):postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

    2.4.3 分散配置:Spring容器定义bean信息集中在一个配置文件里,不利于维护和修改,容易形成硬性编码

      ApplicationContext上下文容器自带引用加载properties类型文件实现类:PropertyPlaceholderConfigurer

      在xml配置文件里添加以下代码,加载属性,可以使用${key}来获取properties属性文件所对应的值     

      <bean id="xxx" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

        <property name="location">

          <value>xxx.properties</value>

            <value>...</value>

        <property>

      </bean>

    2.4.4 属性类型编辑器:对参数值类型转换接收

      。。。

    2.4.5 解析文本信息

      。。。

    2.4.6 监听事件:ApplicationContext容器在生命周期中默认会触发许多事件

      触发事件:ContextCloseEvent--应用上下文关闭时触发  ContextRefreshedEvent--应用上下文初始化或刷新时触发  RequestHandledEvent--Web服务应用上下文中请求被处理后触发

        这个三个事件类都是抽象类org.springframework.context.ApplicationEvent的子类

      监听事件处理:实现org.springframework.context.ApplicationListener接口,实现onApplicationEvent方法,并在spring配置文件里注册bean

    2.4.7 设置触发事件

      。。。

    2.4.8 感知bean:用于获取bean属性信息

      常用接口:BeanNameAware--获取beanID  BeanFactoryAware--获取bean容器  ApplicationContextAware--获取bean容器

        bean类实现BeanNameAware接口,获取beanID值

          //声明属性,设置属性值,注册bean后,自动加载属性赋值          

          public class GetBeanName implements BeanNameAware{
            private String beanName;
            public void setBeanName(String beanName){
              this.beanName = beanName;
            }
          }

        bean类实现BeanFactoryAware接口,获取容器

          //声明属性,设置属性值,注册bean后,自动加载属性赋值

          public class GetBeanFactory implements BeanFactoryAware{
            private BeanFactory factory;
            public void setBeanFactory(BeanFactory factory){
              this.factory= factory;
            }
          }

        bean类实现ApplicationContextAware接口,获取容器

          //声明属性,设置属性值,注册bean后,自动加载属性赋值

          public class GetBeanFactory implements ApplicationContextAware{
            private ApplicationContext context;
            public void setApplicationContext(ApplicationContext context){
              this.context = context;
            }
          }

    

第三章:创建切面

  3.1 AOP介绍

    3.1.1 定义AOP术语:切面(Aspect)、连接点(Joinpotion)、通知(Advice)、切入点(Pointcut)、引入(Introduction)、目标对象(Target)、代理(Proxy)、织入(Weaving)

    3.2.2 Spring的AOP实现

        。。。

  3.2 创建通知

    

    3.2.1 前置通知:目标方法前执行

复制代码
//创建通知实体类,实现前置通知接口,复写接口方法
public class WelcomeAdvice implements MethodBeforeAdvice{//Method:目标方法//args:目标方法参数列表//target:目标对象public void before(Method method, Object[] args, Object target){//具体通知逻辑业务
    }
}
复制代码
复制代码
<!-- 配置文件 -->
<bean id="xxx1" class="目标对象" /><bean id="xxx2" class="具体通知对象"><bean id="xxx3" class="org.springframework.aop.framework.ProxyFactoryBean(代理对象)"><property name="proxyInterfaces(目标对象实现的接口类)"><value>xxx.xxxxx.xxxx.xxx4</value></property><property name="interceptorNames(通知列表)"><list><value>xxx2</value>...</list></property><property name="target(目标对象)"><value>xxx1</value></property>
</bean>
复制代码

    3.2.2 后置通知:目标方法后执行

复制代码
//创建通知实体类,实现后置通知接口,复写接口方法
public class ThankYouAdvice implements AfterReturningAdvice{//returnValue:目标方法的返回值//Method:目标方法//args:目标方法参数列表//target:目标对象public void afterReturning(Object returnValue, Method method, Object[] args, Object target){//具体通知逻辑业务
    }
}
复制代码

    3.2.3 环绕通知:目标方法前后都行,但需要手动调用目标方法并返回值

复制代码
//创建通知实体类,实现环绕通知接口,复写接口方法
public class OnePerCustomerInterceptor implements MethodInterceptor{//MethodInterceptor:封装目标对象相关类public Obeject invoke(MethodInvocation invocation){//手动调用目标方法,返回目标方法返回值Obeject xxx = invocation.proceed();//手动返回return xxx;}
}
复制代码

    3.2.4 异常通知:调用目标方法抛出异常时执行

      实现ThrowsAdvice接口,并覆盖void afterThrowing(Throwable throwable)与void afterThrowing(Throwable throwable,  Method method, Object[] args, Object target)任意一个方法

    3.2.5 引入通知:给目标对象添加行为或属性

      。。。

  3.3 定义切入点:定义通知在那些地方应用

    3.3.1 在Spring中定义切入点

复制代码
//切入点核心接口
public interface Poincut{//类过滤ClassFilter getClassFilter();//方法过滤MethodMatcher getMethodMatcher();
}
复制代码
//类过滤接口
public interface ClassFilter{//根据类名过滤boolean maches(Class clazz);
}
复制代码
//方法过滤接口
public interface MethodMatcher{//判断是否目标方法是否需要通知boolean maches(Method m, Class targetClass);//如果maches返回true,则调用判断是静态通知还是动态通知public boolean isRuntime();//只有isRuntime返回true,则为动态通知,才会执行以下方法public boolean maches(Method m, Class targetClass, Object[] args);
}
复制代码

    提示:尽量使用静态通知,动态通知对性能会有消耗

    3.3.2 理解Advisor:通知与切入点整合接口类

复制代码
//Advisor接口
public interface PointcutAdvisor{//获取切入点类
    Pointcut getPointcut();//获取通知类
    Advice getAdvice();
}
复制代码

    3.3.3 使用Spring的静态切入点

      父类:StaticMethodMatcherPointcut

      常用子类(名称映射):NameMatchMethodPointcut

        映射方法:public void setMappedName(String), public void setMappedName(String[]);

      配置NameMatchMethodPointcut类型切入点:

复制代码
<beans><bean id="xxx1" class="(目标实例类)"/><bean id="xxx2" class="(通知类)"/><!-- 定义切入点 --><bean id="xxx3" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"><!-- 定义通知切入的规则 --><property name="mappedName"><value>order*</value><!-- 不适用通配符,指定具体切入方法 <list><value>orderxxx1</value><value>orderxxx2</value></list>--></property>    <!-- 绑定切入点的通知 --><property name="advice"><ref bean="xxx2" /></property></bean><!-- 切面代理类 --><bean id="xxx4" class="org.springframework.aop.framework.ProxyFactoryBean(代理对象)"><property name="proxyInterfaces(目标对象实现的接口类)"><value>xxx.xxxxx.xxxx.xxx5</value></property><property name="interceptorNames(通知列表)"><list><value>xxx3</value>...</list></property><property name="target(目标对象)"><value>xxx1</value></property></bean>
</beans>
复制代码

      规则表达式切入点:RegexpMethodPointcut

      配置RegexpMethodPointcut类型切入点:

复制代码
<beans><bean id="xxx1" class="(目标实例类)"/><bean id="xxx2" class="(通知类)"/><!-- 定义切入点 --><bean id="xxx3" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><!-- 定义通知切入的规则 --><property name="pattern"><!-- 定义通知切入的规则:所有类以get开头,后面至少有一个字符,接着有By,再后面至少有一个字符 --><value>.*get.+By.+</value></property>    <!-- 绑定切入点的通知 --><property name="advice"><ref bean="xxx2" /></property></bean><!-- 切面代理类 --><bean id="xxx4" class="org.springframework.aop.framework.ProxyFactoryBean(代理对象)"><property name="proxyInterfaces(目标对象实现的接口类)"><value>xxx.xxxxx.xxxx.xxx5</value></property><property name="interceptorNames(通知列表)"><list><value>xxx3</value>...</list></property><property name="target(目标对象)"><value>xxx1</value></property></bean>
</beans>
复制代码

    3.3.4 动态切入点

      。。。

    3.3.5 切入点合并与交叉:通过切入点与切入点、对象、方法、等等的组合与交集形成新的切入点,创建一个实体类,编写参数切入点组合,通过属性配置bean注入切入点参数

      1.编写切入点组合工具类

复制代码
//编写组合代码工具类
public class UnionPointcut implements Pointcut{//声明合并的Pointcut实例private Pointcut delegate;//接口方法public ClassFilter getClassFilter(){return getDelegate().getClassFilter();}public MethodMatcher getMethodMatcher(){return getDelegate().getMethodMatcher();}//声明异常private Pointcut getDelegate(){if(delegate == null){throw new AopConfigException("No pointcuts have configured.");}return delegate;}//组合切入点的逻辑代码public void setPointcuts(List pointcuts){if(pointcuts == null || pointcuts.size() == 0){throw new AopConfigException("Must have at least one Pointcut.");} }delegate = (Pointcut)pointcuts.get(0);for(int i = 1; i<pointcuts.size(); i++){Pointcut pointcut = (Pointcut)pointcuts.get(i);delegate = Pointcuts.union(delegate, pointcut);}
}
复制代码

      配置<bean id="xxx" class="xxx.xxx.UnionPointcut"><property name="pointcuts"><Lits><value>xxx</value>...</List></property></bean>

    2.编写切入点交集工具类:

      。。。

  3.4 创建引入切面:对已有的实体类添加行为或属性

    。。。

   3.5 ProxyFactoryBean详解

    常用属性:target、proxyInterfaces、interceptorNames

    

    

  3.6 自动代理:BeanNameAutoProxyCreator、DefaultAutoProxyCreator

    BeanNameAutoProxyCreator可以的代理类型:切入点、通知、拦截器,DefaultAutoProxyCreator只能代理切入点(Advisor)

    BeanNameAutoProxyCreator配置

复制代码
<bean id="xxx1" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><property name="beanNames"><list><!-- 正则表达式 --><value>*Service</value></list></property><property name="interceptorNames"><value>xxx(切入点、通知、拦截器)</value></property>
</bean>
复制代码

    DefaultAutoProxyCreator配置:

复制代码
<bean id="xxx1" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><property name="advice"><ref bean="xxx2(通知)"></property><property name="pattern"><value>.+Service\..+</value></property>
</bean>
<!-- 自动代理Advisor通知 -->
<bean id="xxx3" class="org.springframework.aop.framework.autoproxy.DefaultAutoProxyCreator"/>
复制代码

  

  

    

这篇关于Spirng+In+Action(Craig Walls Ryan Breidenbach)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/432670

相关文章

Unable to instantiate Action, goodsTypeAction, defined for 'goodsType_findAdvanced' in namespace '/

报错: Unable to instantiate Action, goodsTypeAction,  defined for 'goodsType_findAdvanced' in namespace '/'goodsTypeAction......... Caused by: java.lang.ClassNotFoundException: goodsTypeAction.......

用ajax json给后台action传数据要注意的问题

必须要有get和set方法   1 action中定义bean变量,注意写get和set方法 2 js中写ajax方法,传json类型数据 3 配置action在struts2中

使用http-request 属性替代action绑定上传URL

在 Element UI 的 <el-upload> 组件中,如果你需要为上传的 HTTP 请求添加自定义的请求头(例如,为了通过身份验证或满足服务器端的特定要求),你不能直接在 <el-upload> 组件的属性中设置这些请求头。但是,你可以通过 http-request 属性来自定义上传的行为,包括设置请求头。 http-request 属性允许你完全控制上传的行为,包括如何构建请求、发送请

【CF】D. Arthur and Walls(BFS + 贪心)

D题 解题思路就是每次检查2X2的方格里是否只有一个‘*’,如果有的话这个*就需要变成‘.’,利用BFS进行遍历,入队的要求是这个点为. 一开始将所有的'.'全部加入队列,如果碰到一个'*'变成'.'就入队,判断的时候从4个方向就行判断 题目链接:http://codeforces.com/contest/525/problem/D #include<cstdio>#include<

Flink整合Oozie Shell Action 提交任务带Kerberos认证

最近这段时间一直在忙新集群迁移,上了最新的cdh6.3.0 于是Flink 提交遇到了许多的问题,还好有cloudera License 有了原厂的帮助和社区的伙伴,问题解决起来快了不少。 集群具体情况是 CDH6.3.0 Flink1.8.1,整个数据平台全部组件都上了kerberos和ldap因为要过认证,所以任务提交方法我们选择统一Oozie提交任务,并且因为kerberos认证,还需要F

Servlet mapping specifies an unknown servlet name Action

看一下web.xml中<servlet-mapping>有没有配错

【ssh学习笔记】struts2的action与Spring

//由struts-spring-plugin管理,不需要加@Resource,或在<span style="font-family: Arial; font-size: 14px; line-height: 26px;">applicationContext.xml</span>中也不需要配置该bean //需要注入的对象也不需要加@Resource public class JsonA

Android中常用Action

Android中常用Action 2010-08-10 14:07 标准的Activity Actions ACT ION_MAIN                              作为一个主要的进入口,而并不期望去接受数据 ACT ION_VIEW                            向用户去显示数据 ACT ION_ATTACH_

github中action作用和讲解

1,简介 GitHub Actions 是 GitHub 的一个自动化功能,它允许你在 GitHub 仓库中自动执行软件开发工作流程。你可以使用 GitHub Actions 来执行各种任务,比如: 自动测试:每当代码被推送到仓库时,自动运行测试来确保代码质量。持续集成:自动构建和部署代码,确保新的代码更改不会破坏现有功能。代码格式化:自动格式化代码,以保持代码风格的一致性。自动部署:将代

Zotero tags(action and tags for zotero)怎么使用

先在下面的网址安装action and tags for zotero: https://github.com/windingwind/zotero-actions-tags 视频讲解: Zotero Tag -> Actions and Tags for Zotero - 远不止标签管理!_哔哩哔哩_bilibili 使用方法: 找到一些表情:https://getemoji.