【阅读笔记】《轻量级JavaEE企业应用实战》(第八章)

本章主要包含Spring的AOP和Spring和Hibernate和Struts整合

后处理器

Bean后处理器会在Bean实例创建成功之后,对Bean实体进行进一步的增强处理。
Bean后处理器必须实现BeanPostProcessor接口,该接口中包含两个方法postProcessAfterInitialization和postProcessBeforeInitialization,分别代表初始化之后执行和初始化之前执行,以下是一个小例子

package com.util;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("Bean后处理器的postProcessAfterInitialization方法");
        System.out.println("beanName=" + beanName);
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("Bean后处理器的postProcessBeforeInitialization方法");
        System.out.println("beanName=" + beanName);
        return bean;
    }

}

还可以通过bean标签中init-method设置这个bean的初始化方法,用destory-method来设置这个bean的销毁方法,这些方法是写在这个bean所对应的类中的。

容器后处理器

除了创建Bean的后处理器之外还可以创建Spring容器的后处理器,我们只需要实现BeanFactoryPostProcessor接口即可,它里面有一个postProcessBeanFactory方法,方法参数ConfigurableListableBeanFactory就是Spring容器

属性占位符配置器

想在xml文件中使用.propertiest文件中的内容就可以看看下面的代码了。
在application.xml文件中加入

    <bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
        <property name="locations">
            <list>
                <value>classpath:dbconn.properties</value>
            </list>
        </property>
    </bean>

    <!-- 数据库相关配置 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close"
        p:driverClass="${dataSource.driverClass}"
        p:user="${dataSource.user}"
        p:password="${dataSource.password}"
        p:jdbcUrl="${dataSource.jdbcUrl}"
        p:maxPoolSize="${dataSource.maxPoolSize}"
        p:minPoolSize="${dataSource.minPoolSize}"
        p:initialPoolSize="${dataSource.initialPoolSize}"
        p:maxIdleTime="${dataSource.maxIdleTime}"
    />

之后在src文件夹下创建dbconn.properties,它的文件内容是

dataSource.driverClass = com.mysql.jdbc.Driver
dataSource.user = root
dataSource.password = root
dataSource.jdbcUrl = jdbc:mysql://localhost/spring
dataSource.maxPoolSize = 40
dataSource.minPoolSize = 2
dataSource.initialPoolSize=2
dataSource.maxIdleTime=30

Spring的“零配置”支持

如果不想用xml配置的话,也可以用annotation,在Spring中提供了一下几个annotation来配置Spring Bean类
* @Component:标注一个普通的Spring Bean类
* @Controller:标注一个控制器组件类
* @Service:标注一个业务逻辑组件类
* @Repository:DAO组件类
配置好了这些annotation之后只需要在application.xml文件中加入
<context:component-scan base-package=""></context:component-scan>
来指定Spring自动搜索这些包下的Java类,并以注解来生成Bean实例。使用的时候要注意的是:
* @Component可以带一个字符串类型的参数用作bean的id
* @Scope可以带“prototype”或者别的范围来指定bean的使用范围
* @Resourceo(name=”beanName”)可以用来配置依赖
* @PostConstruct和@PreDestroy来配置定制生命周期的行为,比如说init和close
* @Lazy可以带一个boolean类型的参数,如果为true就不会预初始化该Bean
* @DependsOn({beanName1,beanName2})可以强制初始化bean1和bean2,就算bean1、bean2设置成@Lazy(true)
* @Autowired,是用来自动装配的,可以在bean的set方法上加入@Autowired或者在构造函数上加入,哪怕参数有多个也不要紧,Spring就会自动按照类型搜索出合适的bean。@Autowired可以精确的利用类型(泛型)执行自动装配,但是如果有两个不同的bean他们的类型是同样的可这么办呢?这时我们可以通过@Qualifier来通过bean的id自动装配

资源访问

访问类加载路径里的资源

book.xml文件放在src文件下

        ClassPathResource resource = new ClassPathResource("book.xml");
        System.out.println(resource.getFilename());
        System.out.println(resource.getDescription());
        SAXReader reader = new SAXReader();
        Document document = reader.read(resource.getFile());
        Element root = document.getRootElement();
        System.out.println("root="+root.getText());
        List list = root.elements();
        for(int i = 0; i < list.size(); i++) {
            Element book = (Element) list.get(i);
            System.out.println(i+":"+book.getText());
        }
访问文件系统里的资源

book.xml在与WebContent文件夹同一级

FileSystemResource resource = new FileSystemResource("book.xml");
访问网络资源

网络资源需要使用InputStream流来读取数据,不可以直接getFile的

            UrlResource resource = new      UrlResource("http://hxu0170466.my3w.com/book.xml");
        System.out.println(resource.getFilename());
        System.out.println(resource.getDescription());
        SAXReader reader = new SAXReader();
        Document document = reader.read(resource.getInputStream());
        Element root = document.getRootElement();
        System.out.println("root="+root.getText());
        List list = root.elements();
        for(int i = 0; i < list.size(); i++) {
            Element book = (Element) list.get(i);
            System.out.println(i+":"+book.getText());
        }

与之类似的还有ServletContextResource访问相对于ServletContext路径下的资源、InputStreamResource访问输入流资源、ByteArrayResource访问字节数组资源。

将Resource作为属性

如果某一个Bean中需要使用某个文件的内容,那么我们就可以在这个Bean里面自动注入一个Resource实例,在配置bean的<bean>标签中加入 p:res="classpath:book.xml"(这个bean有一个Resource类型的res属性)这样在这个bean中就可以获取到类加载路径下的book.xml文件的内容了。

在ApplicationContext使用资源
Resource r = applicationContext.getResource("book.xml")

就可以获得到book.xml的文件内容了,这是以applicationContext的访问策略来判定的,applicationContext是通过classpath来创建的那么book.xml就应该放在class加载路径下。

Spring的AOP

AOP(Aspect Orient Programming),是指面向切面编程。与面向对象编程做对比的话可以这样说,面向对象是从静态的角度考虑程序结构,面向切面编程则是从动态角度考虑程序的运行过程。

为什么需要AOP

AOP可以在不修改源代码的前提下增加系统的功能,如果只是用OOP的话如果要在某一个模块上添加一个用户合法验证的话就需要在需要验证的类里面添加验证代码,如果这种类有很多的话那么修改起来是很麻烦的,这时我们就可以通过使用AOP的方式添加一些新的功能(虽然我觉得拦截器也可以做到同样的效果),常常用AOP来处理一些具有横切性质的系统级服务,如事物管理、安全检查、缓存和对象池管理等。总之,AOP要达到的效果是:保证在程序员不修改源代码的前提下,位系统中业务组件的多个业务方法添加某种通用的功能。但AOP的本质是,依然要去修改业务组件的多个业务方法的源代码——只是这个修改由AOP框架完成,而不是程序员。

AOP的基本概念
AOP框架的两个特征
  • 各步骤之间的良好隔离性
  • 源代码无关性
面向切面编程的一些术语
  • 切面(Aspect):切面用于组织多个Advice,Advice放在切面中定义
  • 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或者异常的抛出。Spring AOP中,连接点总是方法的调用
  • 增强处理(Advice):AOP框架在特定的切入点执行的增强处理。处理有“around”、“before”和“after”等类型
  • 切入点(Pointcut):可以插入增强处理的连接点。简而言之,当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。
  • 引入:将方法或字段添加到被处理的类中。
  • 目标对象:被AOP框架进行增强处理的对象。
  • AOP代理:AOP框架创建的对象,简单的说,代理就是目标对象的加强。
  • 织入(Weaving):将增强处理添加到目标对象中,并创建一个被增强的对象(AOP代理)的过程就是织入。
Spring的AOP支持

Spring AOP采用的是基于代理的AOP方案,这与AspectJ采用的编译时增强的解决方案不同。
AOP代理的方法 = 增强处理 + 目标对象的方法

基于注解的“零配置”方式

(CSDN同时打开两个markdown会自动合并。。刚刚写的那些文字都白写了T_T)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值