Spring
1.spring是什么?
是轻量级的开源框架,一站式框架(为javaEE的每一层提供解决方案称为一站式)。
Web层:struts,webwork,struts2,springMVC
Service层:spring
Dao层:dbutils,hibernate,springJDBCtemplement
2.Spring有什么用?
方便解耦,简化开发(IOC通过工厂模式+反射机制实现对象创建)
AOP编程的支持
声明式事务的支持
方便程序测试
方便与其他优秀框架集成
降低javaEE API使用难度
3.Spring的核心思想?
IOC:控制反转,描述:
控制----
反转----
AOP:面向切面编程
4.Spring中遇到的问题
5.Spring IOC的测试项目搭建
需求:IOC控制反转,通过spring来创建对象,调用对象中的方法。
①导入spring-IOC操作需要的jar
②创建需要被管理的类
③创建spring配置文件,一般情况下放在src目录下,命名为:applicationContext.xml
④在applicationContext.xml中引入约束。
A.找到约束所在位置
B.配置bean
⑤创建测试类测试
6.spring的bean管理
6.1bean管理:
即不需要通过new创建对象,通过配置文件<bean>来管理创建对象
6.2bean管理的两种方式:
①使用配置文件的方式
②使用注解的方式实现
6.3bean实例化的三种方式:
①使用无参数构造
Bean提供无参的构造器,通过ApplicationContext的子类,new ClassPathXmlApplicationContext来加载配置文件,获得bean的全路径,通过反射创建对 象,产生实例。
②使用静态工厂
BeanFactory提供静态方法,生成类的实例。
例如:User.java需要创建实例,
A.创建BeanFactory ,在BeanFactory中提供静态方法
Public static User getUser(){
Return new User();
}
B.配置applicationContext.xml
<bean id=”user” class=”工厂的全类名” factory-method=”getUser静态方法”></bean>
③使用实例工厂
注:静态工厂与实例工厂的区别?
Hibernate中sessionFactory为一个实例工厂,先创建工厂,再通过工厂创建session对象。
6.4spring 配置文件bean标签中的常用属性
<bean id=”” class=””></bean>
Bean标签中的属性解释:
①id:根据id的值,可以取到配置对象,(不能存在特殊符号)例如:
ApplicationContext applicationContext
= New ClassPathXmlApplicationContext(“applicationContext.xml”);
Object obj = applicationContext.getBean(“id的值”);
②class:要创建对象类的全路径
通过id--->得到class,通过类的反射机制--->创建该类的实例
③scope属性:
A.singleton表示创建单例对象
B.Prototype表示创建多实例对象。(action为多实例)
c.request创建对象之后,把对象放到request域
d.session创建对象之后,把对象放到session域
e.globalsession创建对象之后,把对象放到globalsession域
④name属性(可以存在特殊符号),与id功能一样。
6.5spring 依赖注入(支持属性与有参构造)
IOC的类型(属性注入,构造注入,接口注入)
6.5.1属性注入
注入属性
①可以通过set()方法进行注入
②可以通过有参构造传参(成员变量)
③可以通过接口注入
Spring注入对象(set,对象作为参数构造注入)
P名称空间注入步骤:
①创建约束xmlns:p="http://www.springframework.org/schema/p"
②
注入复杂属性
①属性类型数组
②属性类型是list
③属性类型是set
④属性类型map集合
⑤属性类型Properties类型
6.5.2有参构造的注入
6.5.3接口注入
7.IOC与DI之间的关系
7.1IOC:控制反转--创建对象交给spring容器管理
例如:创建dao对象
<bean id=”userDao” class=”com.gsy.dao.UserDao”></bean>
通过 new ClassPathXmlApplicationContext(“applicationContext.xml”),getBean()方法创建userDao对象,之前通过service层 new userDao()
这个创建对象的权利--称之为控制,原来通过service new创建对象,现在通过spring创建对象--称之为反转。
7.2DI:依赖注入---创建对象的过程中,向属性设置值
7.3IOC与DI的关系
依赖注入的前提是需要在控制反转的基础上进行,不能单独进行依赖注入。
例如:创建dao对象
<bean id=”userDao” class=”com.gsy.dao.UserDao”></bean>
创建service对象
<bean id=”userService” class=”com.gsy.service.UserService”>
通过属性依赖注入:service中存在成员userDao,且存在setter方法
<property name=”userDao” ref=”userDao”>
</bean>
Spring配置文件什么时候被加载?
服务器启动的时候,创建servletContext对象,使用监听器监听到,创建servletContext对象创建之后,spring配置文件被加载,对象被创建。
Bean对象创建后放在哪里? 放在ServletContext,无论在哪一层,都可以访问得到。
8.spring使用注解来实现bean管理(创建对象)
优点:替代部分配置文件。
缺点:还需要写配置文件,不可能完全替代。
Bean管理使用配置文件,能够完成对象的创建,属性注入。这个操作也可以通过注解的方式来完成。
使用注解创建对象的步骤:
①Spring注解是通过配置文件中对包中的资源文件进行扫描,spring的注解依赖aop.jar
如图:如果不添加aop.jar会提示
添加jar:spring-aop-4.2.4.RELEASE.jar
②添加注解约束:
③配置开启注解扫描:检查配置的包下的类,方法,属性上是否有注解
<context:component-scan base-package=”要扫描的包”>
只会扫描属性上的注解:
<context:annotation-config></context:annotation-config>
④在创建对象所在的类上面使用注解实现
Dao层实现类:@Repository
Service层实现类:@Service
Controller层实现类:@Controller
@Component----
上述都可以创建所有类的对象,但是最好通过上述三种来标注分层。
注:可以结合@scope(value=”prototype”)创建多实例对象,例如:
@Controller
@Scope(value=”prototype”)
Public void Controller(){}
9.使用注解注入属性(对象)
需求:service层需要通过注解来使用dao对象
方式①通过xml配置,通过service中创建dao的成员变量,并且提供set(),配置文件中,先通过spring bean管理创建dao,service的对象,再通过设置属性
<property name=”dao” ref=”引用dao bean管理的id”>
方式②:使用注解来使用dao对象在service的注入:
优点:不需要set方法,不需要在<bean>service配置中添加属性依赖。
操作步骤:
①导包:注解依赖aop.jar
②创建dao类,service类,在service类中声明成员dao
③配置文件applicationContext.xml中配置:
开启扫描注解,扫描该包下的类,属性,方法上是否存在注解。
<context:component-scan package-scan=”com.gsy”>
④在dao类,service类上添加注解
Dao类添加:@Respository
Service类添加:@Service
Service类中的属性dao:@Autowired或者@Resource(value=”xxxDao”)
10.spring AOP
10.1什么是AOP?
AOP:面向切面编程。即在不修改源代码的基础上从切面的角度去增加新的功能实现。
增强方法的解决方案有:①继承②装饰者模式③动态代理
装饰者模式:使用场景:在BufferedReader中使用装饰者模式对FileReader进行了装饰。
特点:①装饰者与被装饰者实现同一接口。②装饰者拥有被装饰者类做为成员,提供有参构造来实例化对象。③装饰者类实现接口中方法可对被装饰者中方法进行增强。
动态代理:通过创建代理对象,用于控制原对象的引用。
与装饰者模式的区别是:装饰者模式是对对象的增强,而动态代理是通过增强代理对象来实现增强,不改变原对象,只是对代理的对象控制,代理类可以对客户隐藏对象的具体信息。
使用场景分析:
装饰者模式:BufferedReader对FileReader增强
动态代理:增强HttpRequest中的getParamter()处理中文乱码
源码分析:
动态代理的分类:
①JDK中对存在实现接口的类使用Proxy对象
②Cglib对没有接口的类创建资料类对象实现,
①创建代理类
②使用Enhancer的setSuperClass()指定其父类,设置增强器的父类
③使用方法回调,setCallBack(匿名内部类创建MethodInterceptor方法拦截的实例对象)
纵向机制:
模板设计模式:通过提供父类,让子类继承实现方法的增强,缺点就是父类中提供的方法名改变,所有子类都需要改变
横向机制:
通过动态代理,来完成切点切入,即创建代理对象来完成对方法的增强。
10.2AOP中的术语
PointCut(切入点):即需要对哪个方法增强,那个方法就是切入的点。
Advice(通知/增强):增强了什么内容,比如:需要在转账方法之前开启事务,添加事物这个功能就表示前置通知/增强。
通知包括:前置通知,后置通知,环绕通知,异常通知,最终通知。
前置通知:<aop:before/>
最终通知:<aop:after/>
后置通知:<aop:after-returning method=""/>
环绕通知:<aop:around method=""/>
异常通知:<aop:after-throwing method=""/>
关于后置通知与最终通知的区别:
后置通知--切入点方法里面抛出异常,通知不会执行
最终通知--切入点方法里面抛出异常,通知会执行
Target(目标对象):代理的目标对象
Weave(织入): 指将aspects应用到target对象并导致proxy对象创建的过程称为织入 .
Introduction(引入):在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或Field
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类。
Aspect(切面):把增强 应用到切入点中。即对增强的方法实现增强。
10.3AOP操作
Spring使用aspectJ来完成AOP操作。aspectJ是面向切面的一个框架,不是spring的一部分,经常与spring一起完成AOP操作
操作的方式:
①使用aspectJ的xml配置文件
②使用aspectJ的注解
操作步骤:
A.(使用xml配置文件实现AOP)
aspectJ基于表达式的形式进行 切入点配置
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
①导入基本jar
以及aop与aspectJ的相关jar
②切入点配置,例如:service层依赖dao层的配置
Dao类中需要添加事物
B.使用aspectJ注解实现AOP