版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
北京传智播客教育
第一章开始spring之旅北京传智播客教育
知识1:Spring介绍Spring是一个非常活跃的开源框架;它是一个基于IOC和AOP来构架多层JavaEE系统的框架,它的主要目地是简化企业开发.Spring以一种非侵入式的方式来管理你的代码,Spring提倡”最少侵入”,这也就意味着你可以适当的时候安装或卸载Spring北京传智播客教育
知识2:Spring模块介绍Spring框架是一个分层架构,它包含一系列的功能要素,并被分为大约20个模块。这些模块分为CoreContainer、DataAccess/Integration、Web、AOP(AspectOrientedProgramming)、Instrumentation和测试部分,如下图所示:
北京传智播客教育知识3:理解控制反转(IOC)IOC就是InversionofControl
public
classGirl{privateBoyboy=newBoy();public
voidkiss(){System.out.println(boy.getBoyObject());}}boy是在应用内部创建及维护的。所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转,目的是为了获得更好的扩展性和良好的可维护性。北京传智播客教育知识4:理解依赖注入(DependencyInjection)当我们把依赖对象交给外部容器负责创建,那么Girl类可以改成如下:public
classGirl{privateBoyboy;public
voidkiss(){System.out.println(boy.getBoyObject());}}所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。北京传智播客教育知识点5:实现IOC*org.springframework.asm-3.0.2.RELEASE.jarSpring独立的asm程序,Spring2.5.6的时候需要asmJar包,3.0开始提供他自己独立的asmJar。*org.springframework.beans-3.0.2.RELEASE.jar所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行InversionofControl/DependencyInjection(IoC/DI)操作相关的所有类*org.springframework.context-3.0.2.RELEASE.jarSpring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等。*org.springframework.core-3.0.2.RELEASE.jar包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心。*org.springframework.expression-3.0.2.RELEASE.jarSpring表达式语言*mons.logging-1.1.1.jar(spring-framework-3.0.2.RELEASE-dependencies)第三方的主要用于处理日志1:到/download下载spring,然后进行解压缩,在解压目录中找到下面jar文件,拷贝到类路径下北京传智播客教育
知识点5:实现IOC2:创建java类public
classBoy{public
voiddisplay(){
System.out.println("随便");}}北京传智播客教育
知识点5:实现IOC3:创建spring的配置模板<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd“></beans>该配置模版可以从spring的参考手册或spring的例子中得到。配置文件的取名可以任意,文件可以存放在任何目录下,但考虑到通用性,一般放在类路径下。北京传智播客教育
知识点5:实现IOC4:在spring的配置文件中增加如下配置<beanid="boy"class="cn.itcast.ioc.Boy"></bean>北京传智播客教育知识点5:实现IOC5:加载spring的配置文件测试public
classApp{
public
static
voidmain(String[]args){
//在类路径下,初始化spring容器
ApplicationContextctx=newClassPathXmlApplicationContext("beans.xml");
//从spring容器中获取boy对象<beanid="boy"class="cn.itcast.ioc.Boy"></bean>Boyboy=(Boy)ctx.getBean("boy");
//调用boy对象的display方法
boy.display();}}北京传智播客教育知识点6:实现DI1.创建girl类public
classGirl{privateBoyboy;public
voidsetBoy(Boyboy){System.out.println("setBoy"+boy);this.boy=boy;}public
voidkiss(){boy.display();}}北京传智播客教育
知识点6:实现DI2.在spring的beans.xml文件中增加如下配置,红色的为新增加的<beanid="boy"class="cn.itcast.di.Boy"></bean>
<!--创建girl的对象-->
<beanid="girl"class="cn.itcast.di.Girl"><!--依赖注入把boy对象传递给girlpropertyname="boy1"使用publicvoidsetBoy1(Boyboy1)
<propertyname="boy"><!--引用beanid="boy"中的boy--><refbean="boy"/></property></bean>北京传智播客教育
知识点6:实现DI3.测试public
classApp{
public
static
voidmain(String[]args){
//加载spring的xml文件,初始化spring容器
ApplicationContextctx=newClassPathXmlApplicationContext("cn/itcast/di/beans.xml");
//从spring容器中获取Girl对象<beanid="girl"class="cn.itcast.di.Girl">Girlgirl=(Girl)ctx.getBean("girl");
//调用boy对象的display方法
girl.kiss();}}北京传智播客教育知识点7:从spring容器中得到bean当spring容器启动后,因为spring容器可以管理bean对象的创建,销毁等生命周期,所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。从容器获取bean对象的代码如下:ApplicationContextctx=newClassPathXmlApplicationContext("beans.xml");
Girlgirl=(Girl)ctx.getBean("girl");北京传智播客教育知识点8:实例化spring容器的方式实例化Spring容器常用的两种方式:方法一:在类路径下寻找配置文件来实例化容器ApplicationContextctx=newClassPathXmlApplicationContext(newString[]{"beans.xml"});可以在整个类路径中寻找xml文件*通过这种方式加载。需要将spring的配置文件放到当前项目的classpath路径下*classpath路径指的是当前项目的src目录,该目录是java源文件的存放位置。方法二:在文件系统路径下寻找配置文件来实例化容器ApplicationContextctx=newFileSystemXmlApplicationContext(newString[]{“d:\\beans.xml“});Spring的配置文件可以指定多个,可以通过String数组传入。北京传智播客教育知识点9:为何要使用Spring至少在我看来,在项目中引入spring立即可以带来下面的好处降低组件之间的耦合度,实现软件各层之间的解耦。
可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。当我们使用容器管理事务时,开发人员就不再需要手工控制事务.也不需处理复杂的事务传播。容器提供单例模式支持,开发人员不再需要自己编写实现代码。容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。容器提供的众多辅作类,使用这些类能够加快应用的开发,如:JdbcTemplate、HibernateTemplate。Spring对于主流的应用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,这样更便于应用的开发。ControllerServiceDAO北京传智播客教育
知识点9:使用Spring的好处当使用spring时,我们可以使用容器提供的众多服务北京传智播客教育
第二章装配Bean北京传智播客教育知识点1:三种实例化bean的方式1.使用类构造器实例化(默认无参数)<beanid=“personService"class="cn.itcast.bean.impl.PersonServiceImpl"/>2.使用静态工厂方法实例化(简单工厂模式)<beanid="personService"class="com.itcast.factory.PersonServiceFactory"factory-method="createPersonService"/>public
classPersonServiceFactory{public
staticPersonServicecreatePersonService(){return
newPersonServiceImpl();}}3.使用实例工厂方法实例化(工厂方法模式):<beanid=“personServiceFactory"class="com.itcast.factory.PersonServiceFactory"/><beanid="personService"factory-bean=“personServiceFactory"factory-method="createPersonService"/>publicclassPersonServiceFactory{publicPersonServicecreatePersonService(){returnnewPersonServiceImpl();}}北京传智播客教育知识点2:Bean的作用域*singleton(默认值)
在每个SpringIoC容器中一个bean定义只有一个对象实例(共享)。默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:
<beanid="xxx"class="cn.itcast.OrderServiceBean"lazy-init="true"/>如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:<beansdefault-lazy-init="true“...>*prototype
允许bean可以被多次实例化(使用一次就创建一个实例)*request*session*globalsession(Portlet规范将portlet定义为一种“基于Java技术的web组件,由处理请求和生成动态内容的portlet容器管理”)北京传智播客教育知识点3:指定Bean的初始化方法和销毁方法Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。
<beanid=“foo”class=“...Foo”init-method=“setup”destory-method=“teardown”/>当bean被载入到容器的时候调用setup当bean从容器中删除的时候调用teardown(scope=singleton有效)北京传智播客教育知识点4:依赖注入*手工装配
*使用xml配置文件
*使用属性setter方法注入
4.1
*使用构造器注入
4.2
*使用注解
*autowired注解
4.3
*resource注解
4.4
*自动装配
4.5
*byType:按类型装配
*byName:按名称装配
*constructor装配,*autodetect
不确定装配。注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果。北京传智播客教育知识点4:依赖注入
4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入通过setter方法注入依赖<bean>元素的<property>子元素指明了使用它们的set方法来注入。可以注入任何东西,从基本类型到集合类,甚至是应用系统的bean。北京传智播客教育知识点4:依赖注入通过setter方法注入依赖
*简单bean配置配置bean的简单属性,基本数据类型和String。<beanid="personService"class="com.itcast.bean.impl.PersonServiceImpl"><!--基本类型,string类型--><propertyname="age"value="20"></property><propertyname="name"value="张无忌"></property></bean>
4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育知识点4:依赖注入通过setter方法注入依赖引用其它bean(外部bean)<beanid="person"class="com.itcast.bean.Person"/><beanid="personService"class="com.itcast.bean.impl.PersonServiceImpl"><!--引用类型--><propertyname="person"ref="person"/></bean>
4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育知识点4:依赖注入通过setter方法注入依赖
*内部bean
<beanid="personService"class="com.itcast.bean.impl.PersonServiceImpl"><!--内部bean注入-->
<propertyname="personClass">
<beanclass="com.itcast.bean.PersonClass"/></propert></bean>这种方式的缺点是你无法在其它地方重用这个personClass实例,原因是它是专门为personService而用。4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育依赖注入--手工装配--XML方式通过setter方法注入依赖*装配集合
若bean的属性是集合类型,按如下处理:
A、装配List和数组:<!--装配数组--><propertyname="obj"><list><value>obj1</value><value>obj2</value><refbean="person"/></list></property><!--装配list--><propertyname="lists"><list><value>list1</value><value>list2</value><refbean="person"/></list></property>4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育知识点4:依赖注入通过setter方法注入依赖
*装配集合
B、装配set:
set使用方法和list一样,不同的是对象被装配到set中,而list是装配到List或数组中装配。<!--装配set--><propertyname="sets"><set><value>set1</value><value>set2</value><refbean="person"/></set></property>4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育知识点4:依赖注入通过setter方法注入依赖*装配集合
C、装配map:map中的<entry>的数值和<list>以及<set>的一样,可以使任何有效的属性元素,需要注意的是key值必须是String的。<!--装配map--><propertyname="maps"><map><entrykey="01"><value>map01</value></entry><entrykey="02"><value>map02</value></entry></map></property>4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育知识点4:依赖注入通过setter方法注入依赖*装配集合D、装配Properties:
<!--装配Properties--><propertyname="props"><props><propkey="01">prop1</prop><propkey="02">prop2</prop></props></property>4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育知识点4:依赖注入通过setter方法注入依赖
*装配集合(List)E、设置null:
<!--装配null--><propertyname="listnull"><null/></property>4.1:手工装配
--
使用xml配置文件--
使用属性setter方法注入北京传智播客教育知识点4:依赖注入通过构造函数注入依赖
通过参数的顺序:<constructor-argindex="0"><value>张三</value></constructor-arg><constructor-argindex="1"><value>56</value></constructor-arg>4.2:手工装配
--
使用xml配置文件--
通过构造函数注入北京传智播客教育知识点4:依赖注入通过构造函数注入依赖通过参数的类型:
<!--通过参数的类型--><constructor-argtype="java.lang.Integer"><value>56</value></constructor-arg><constructor-argtype="java.lang.String"><value>张三</value></constructor-arg>4.2:手工装配
--
使用xml配置文件--
通过构造函数注入北京传智播客教育知识点4:依赖注入.在java代码中使用@Autowired或@Resource注解方式进行装配的前提条件是。
1、引入context命名空间需要在xml配置文件中配置以下信息:<beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd
/schema/context/schema/context/spring-context-3.0.xsd">
<context:annotation-config/></beans>
2、在配置文件中添加context:annotation-config标签<context:annotation-config/>这个配置隐式注册了多个对注释进行解析处理的处理器AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
注:@Resource注解在spring安装目录的spring-framework-3.0.2.RELEASE-dependencies\javax.annotation\com.springsource.javax.annotation\1.0.0包下com.springsource.javax.annotation-1.0.0.jar手工装配
--
使用注解方式北京传智播客教育知识点4:依赖注入.注意:*如果使用jdk1.5,需要引入com.springsource.javax.annotation-1.0.0.jar包
*如果使用jdk1.6,不需要引入
com.springsource.javax.annotation-1.0.0.jar包com.springsource.javax.annotation-1.0.0.jar该jar包在spring-framework-3.0.2.RELEASE-dependencies\javax.annotation\com.springsource.javax.annotation\1.0.0包下手工装配
--
使用注解方式北京传智播客教育知识点4:依赖注入Autowired标注在字段上
*@Autowired注解默认按类型进行装配*获取该注解标注的字段的类型---PersonDao类型*以该类型为条件到spring容器(beans.xml)中去查找bean的id节点的类型是PersonDao类型.*找到以后,获取该节点对应的对象,利用反射直接为personDao变量赋值
*@Qualifier(“personDao”)该注解以名字为条件查找依赖对象*以该注解的的参数personDao条件到spring容器(beans.xml)中去查找bean的id节点的值是personDao的对象*找到以后,获取该节点对应的对象,利用反射直接为personDao变量赋值如果不存在该名称,抛出异常4.3:手工装配
--
使用注解方式-autowired注解@AutowiredprivatePersonDaopersonDao;//用于字段上
@Autowired
@Qualifier("personDao")privatePersonDaopersonDao;//用于字段上北京传智播客教育知识点4:依赖注入@AutowiredpublicvoidsetPersonDao(PersonDaopersonDao){//用于属性的set方法上this.personDao=personDao;}@AutowiredpublicvoidsetPersonDao(@Qualifier("personDao")PersonDaopersonDao){//用于属性的set方法上this.personDao=personDao;}4.3:手工装配
--
使用注解方式autowired注解Autowired标注在setter方法上
@Autowired注解默认按类型进行装配
*获取setPersonDao()方法的参数的类型---PersonDao类型
*以该类型为条件到spring容器(beans.xml)中去查找bean的id节点的类型是PersonDao类型. *找到以后,获取该节点对应的对象,把该对象作为实参传递给该setPersonDao(
PersonDaopersonDao)的形参.
*@Qualifier("personDao")该注解以名字为条件查找依赖对象
*以该注解的的参数personDao条件到spring容器(beans.xml)中去查找bean的id节点的 值是PersonDao的对象
*
找到以后,获取该节点对应的对象,把该对象作为实参传递给该setPersonDao(
PersonDaopersonDao)的形参. *如果不存在该名称,抛出异常北京传智播客教育知识点4:依赖注入Resource注解标注在字段上
*@Resource注解默认按名称装配。*如果没有指定name属性*获取该注解标注的字段值---personDao *以该字段值为条件到spring容器(beans.xml)中去查找bean的id节点的值是personDao的节点 *找到以后,获取该节点对应的对象,利用反射直接为personDao变量赋值 *如果没有找到.并且按照默认的名称找不到依赖对象时,@Resource注解会回退到按类型装配 *获取该注解标注的字段类型--PersonDao *以该类型为条件到spring容器(beans.xml)中去查找bean的节点的类型是PersonDao类型的对象 *找到以后,获取该节点对应的对象,利用反射直接为personDao变量赋值*如果指定name属性只能按名称装配 *获取name属性的值personDao *以该值为条件到spring容器(beans.xml)中去查找bean的id节点的值是PersonDao的对象 *找到以后,获取该节点对应的对象,利用反射直接为personDao变量赋值 *如果不存在该名称,抛出异常4.4:手工装配
--
使用注解方式-resource注解
@Resource(name="personDao")privatePersonDaopersonDao;;//用于字段上北京传智播客教育知识点4:依赖注入@Resource(name="personDao")publicvoidsetPersonDao(PersonDaopersonDao){this.personDao=personDao;}4.4:手工装配
--
使用注解方式resource注解resource注解标注在setter方法上
*@Resource注解默认按名称装配。*如果没有指定name属性*获取setPersonDao()方法的属性名---personDao *以该属性名为条件到spring容器(beans.xml)中去查找bean的id节点的值是personDao的节点 *找到以后,获取该节点对应的对象,把该对象作为实参传递给该setPersonDao( PersonDaopersonDao)的形参. *如果没有找到.并且按照默认的名称找不到依赖对象时,@Resource注解会回退到按类型装配 *获取setPersonDao()方法的参数类型---PersonDao *以该类型为条件到spring容器(beans.xml)中去查找bean的节点的类型是PersonDao类型对象 *找到以后,获取该节点对应的对象,把该对象作为实参传递给该setPersonDao( PersonDaopersonDao)方法的形参 *如果指定name属性只能按名称装配 *获取name属性的值 *以该值为条件到spring容器(beans.xml)中去查找bean的id节点的值是PersonDao的对象 *找到以后,获取该节点对应的对象,把该对象作为实参传递给该setPersonDao( PersonDaopersonDao)的形参. *如果不存在该名称,抛出异常北京传智播客教育知识点4:依赖注入对于自动装配,大家了解一下就可以了,实在不推荐大家使用。例子:<beanid=“foo”class=“...Foo”autowire=“autowiretype”>autowire属性取值如下*byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。*byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。*constructor与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。*autodetect:首先尝试使用constructor来自动装配,然后使用byType方式。不确定性的处理与constructor方式和byType方式一致。4.5:自动装配(了解知识)北京传智播客教育
知识点5:指定Bean的初始化方法和销毁方法(注解)Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。
<beanid=“foo”class=“...Foo”init-method=“setup”destory-method=“teardown”/>当bean被载入到容器的时候调用setup注解方式下:
@PostConstruct初始化当bean从容器中删除的时候调用teardown(scope=singleton有效)注解方式如下:
@PreDestroy销毁北京传智播客教育知识点6:classpath自动扫描把组件纳入spring容器中管理前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便。Spring3.0为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:1、引入context命名空间需要在xml配置文件中配置以下信息:<beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd
/schema/context/schema/context/spring-context-3.0.xsd"><context:component-scanbase-package="cn.itcast"/></beans>北京传智播客教育知识点6:classpath自动扫描把组件纳入spring容器中管理2、在配置文件中添加context:component-scan标签<context:component-scanbase-package="cn.itcast"/>其中base-package为需要扫描的包(含子包)。注:1、在使用组件扫描元素时,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor会隐式地被包括进来。也就是说,连个组件都会被自动检测并织入-所有这一切都不需要在XML中提供任何bean配置元数据。
2、功能介绍@Service用于标注业务层组件、@Controller用于标注控制层组件(如struts中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。北京传智播客教育通过在classpath自动扫描方式把组件纳入spring容器中管理//Dao层importorg.springframework.stereotype.Repository;importcom.itcast.dao.PersonDao;@Repository("personDao")public
classPersonDaoBeanimplementsPersonDao{}//业务层importjavax.annotation.Resource;importorg.springframework.stereotype.Service;importcom.itcast.dao.PersonDao;importcom.itcast.service.PersonService;@Service("personService")public
classPersonServiceBeanimplementsPersonService{
@Resource(name="personDao")privatePersonDaopersonDao;}北京传智播客教育
第三章面向切面编程北京传智播客教育
知识点1:AOP--代理对象代理模式:代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题的地方都可以是使用代理主题代理主题(Proxy)角色:代理主题角色内部含有对真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主题控制对真实主题的引用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯地将调用传递给真实主题对象。真实主题角色:定义了代理角色所代表地真实对象代理对象代理主题目标对象真实主题客户端代理模式示意图北京传智播客教育
知识点2:JDK动态代理importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;public
classJDKProxyimplementsInvocationHandler{privateObjecttargerObject;//代理的目标对象
/***创建代理对象*@paramtargerObject目标对象*@return*/publicObjectcreateProxyInstance(ObjecttargerObject){
this.targerObject=targerObject;
/**第一个参数设置代码使用的类加载器,一般采用跟目标类相同的类加载器*第二个参数设置代理类实现的接口,跟目标类使用相同的接口*第三个参数设置回调对象,当代理对象的方法被调用时,会调用该参数指定对象的invoke方法*/
returnProxy.newProxyInstance(targerObject.getClass().getClassLoader(),targerObject.getClass().getInterfaces(),
this);}北京传智播客教育
JDK动态代理/***@paramproxy目标对象的代理类实例*@parammethod对应于在代理实例上调用接口方法的Method实例*@paramargs传入到代理实例上方法参数值的对象数组*@return
方法的返回值没有返回值时是null*/publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("代理类实例"+proxy.getClass());System.out.println("方法名称"+method.getName());if(args!=null&&args.length>0){//方法的参数值
for(inti=0;i<args.length;i++){System.out.println("方法参数值"+args[i].toString());}}Objectreturnvalue=null;//定义方法的返回值没有返回值时是nullreturnvalue=method.invoke(this.targerObject,args);//调用目标对象的方法System.out.println("方法的返回值"+returnvalue);returnreturnvalue;}}北京传智播客教育
知识点3:AOP中的概念Aspect(切面):
是通知和切入点的结合,通知和切入点共同定义了关于切面的全部内容---它的功能、在何时和何地完成其功能joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.Pointcut(切入点):所谓切入点是指我们要对哪些joinpoint进行拦截的定义.通知定义了切面的”什么”和”何时”,切入点就定义了”何地”.Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)Target(目标对象):代理的目标对象Weaving(织入):是指把切面应用到目标对象来创建新的代理对象的过程.切面在指定的连接点织入到目标对象Introduction(引入):在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field.北京传智播客教育
知识点4:代理总结spring在运行期创建代理,不需要特殊的编译器.spring有两种代理方式:1.若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。2.若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。使用该方式时需要注意:1.对接口创建代理优于对类创建代理,因为会产生更加松耦合的系统。对类代理是让遗留系统或无法实现接口的第三方类库同样可以得到通知,这种方式应该是备用方案。2.标记为final的方法不能够被通知。spring是为目标类产生子类。任何需要被通知的方法都被复写,将通知织入。final方法是不允许重写的。
spring只支持方法连接点:不提供属性接入点,spring的观点是属性拦截破坏了封装。面向对象的概念是对象自己处理工作,其他对象只能通过方法调用的得到的结果。北京传智播客教育知识点5:使用CGLIB生成代理CGlib是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。importjava.lang.reflect.Method;importxy.Enhancer;importxy.MethodInterceptor;importxy.MethodProxy;public
classUserManagerCglibProxyimplementsMethodInterceptor{privateObjecttargerObject;//代理的目标对象
/***创建目标对象的代理对象*@paramtargerObject目标对象*@return*/
publicObjectcreateProxyInstance(ObjecttargerObject){
this.targerObject=targerObject;Enhancerenhancer=newEnhancer();//该类用于生成代理对象
enhancer.setSuperclass(this.targerObject.getClass());//设置父类
enhancer.setCallback(this);//设置回调用对象为本身
returnenhancer.create();//创建代理对象}北京传智播客教育
使用CGLIB生成代理/***@paramobj目标对象代理类的实例*@parammethod代理实例上调用父类方法的Method实例*@paramargs传入到代理实例上方法参数值的对象数组*@parammethodProxy使用它调用父类的方法*@return*@throwsThrowable*/publicObjectintercept(Objectobj,Methodmethod,Object[]args,MethodProxymethodProxy)throwsThrowable{System.out.println("代理类"+obj.getClass());System.out.println("方法名称"+method.getName());if(args!=null&&args.length>0){//方法的参数值
for(inti=0;i<args.length;i++){System.out.println("方法参数"+args[i]);}}Objectreturnvalue=null;//方法的返回值,无返回类型时,为nullreturnvalue=methodProxy.invoke(this.targerObject,args);//调用目标对象的方法System.out.println("方法的返回值"+returnvalue);returnreturnvalue;}}北京传智播客教育
使用Spring进行面向切面(AOP)编程要进行AOP编程,首先我们要在spring的配置文件中引入aop命名空间:<beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"
xmlns:aop="/schema/aop"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd
/schema/aop/schema/aop/spring-aop-3.0.xsd"></beans>Spring提供了两种切面使用方式,实际工作中我们可以选用其中一种:基于XML配置方式进行AOP开发。基于注解方式进行AOP开发。北京传智播客教育
使用Spring进行面向切面(AOP)编程要进行AOP编程,需要引入的jar包*.sf.cglib-2.2.0.jarcglib代理*.aopalliance-1.0.0.jar*.aspectj.tools-1.6.6.RELEASE.jar*org.springframework.aop-3.0.2.RELEASE.jarspring的面向切面编程,提供AOP(面向切面编程)实现*org.springframework.aspects-3.0.2.RELEASE.jar
spring提供对AspectJ框架的整合北京传智播客教育
定义切面和通知//切面publicclassSecurity{//通知publicvoidcheckSecurity(JoinPointpoint){System.out.println("进行安全性检查");System.out.println("point.getTarget()"+point.getTarget());
//获取方法调用方法的名称
System.out.println("point.getSignature().getName()"+point.getSignature().getName());
//获取方法的参数
if(point.getArgs()!=null&&point.getArgs().length>0){for(inti=0;i<point.getArgs().length;i++){System.out.println("point.getArgs()"+point.getArgs()[i]);}}}}北京传智播客教育
知识点6:基于XML配置—前置通知配置文件如下<beanid="security"class="com.itcast.service.Security"/><!--定义切面对象--><beanid=“userManager”class=“com.itcast.service.UserManagerImpl”/><!--创建接口实现类目标对象--><aop:config><!--所有的切面和通知都必须定义在aop:config元素内部--><aop:aspectref="security"><!--配置切面-->
<!--声明切入点--><aop:pointcutid="userManagerPointcut"expression="execution(*com.itcast.service..*.save*(..))"/>
<!--声明前置通知,在匹配方法执行前运行--><aop:beforemethod="checkSecurity"pointcut-ref="userManagerPointcut"/></aop:aspect></aop:config>北京传智播客教育
知识点7:基于XML配置—后置通知publicclassSecurity{publicvoidcheckSecurity(JoinPointpoint,Objectretval){System.out.println("进行安全性检查");//获取目标对象方法的返回值
System.out.println("retval返回值:"+retval);
}}配置文件如下<beanid="security"class="com.itcast.service.Security"/><!--定义切面对象--><beanid="userManager"class="com.itcast.service.UserManagerImpl"/><!--创建接口实现类对象--><aop:config><!--所有的切面和通知都必须定义在aop:config元素内部--><aop:aspectref="security"><!--声明切面-->
<!--声明切入点--><aop:pointcutid="userManagerPointcut"expression="execution(*com.itcast.service..*.save*(..))"/>
<!--声明后置通知,在匹配的方法完全执行后运行--><aop:after-returningmethod="checkSecurity"pointcut-ref="userManagerPointcut“returning="retval"/></aop:aspect></aop:config>北京传智播客教育
知识点8:基于XML配置—异常通知publicclassSecurity{publicvoidcheckSecurity(JoinPointpoint,Throwableex){System.out.println("进行安全性检查");//获取异常
System.out.println("ex"+ex);}}配置文件如下<beanid="security"class="com.itcast.service.Security"/>
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 关于2026年供应链管理优化函(7篇)范文
- 湖南省邵阳市洞口县2025年三年级数学下学期期中教学质量检测试题(含答案)
- 传统文化探索:传统节日知多少小学主题班会课件
- 感恩心:小学主题班会课件之母恩犹两仪
- 2026年产品质控流程调整告知函(4篇)范文
- 通知批量扣款安排通知书(3篇范文)
- 企业知识库建设流程规范化手册
- 台风天气初期预警预案社区居民预案
- 电商平台商品详情页优化提升点击率方案
- 抵制校园暴力共建友善成长空间二年级班会课件
- DB37+T+5088-2024地下管线探测技术规程
- 【2026年】叉车理论考试题库(附答案+解析)试卷及答案
- 大连理工大学2026年强基计划校考《面试+体育测试》模拟试题及答案解析
- 2026云南文山州文山市教育体育系统选调中小学教师50人考试参考题库及答案详解
- 银行员工消防安全培训教材
- 26新五 (下) 道德与法治单元知识点梳理
- 2026年工业AI驱动的中国制造新范式白皮书-IDC
- 2025年教育系统遴选笔试真题附答案
- 2026年陕西省八年级地理生物会考试卷题库及答案
- 2026年部编版新教材语文二年级下册期末测试题(有答案)
- GB/T 19877-2026个人用特种清洁剂
评论
0/150
提交评论