一、Spring创建对象的三种方式
1、使用无参构造器创建对象(默认方式,需掌握)
步骤:
(1)导入spring依赖的核心模块的jar包
1)core包;及其依赖的日志包:commons-loggin包
2)context;
3)beans;
4)expression
(2)定义业务类:必须要有无参构造器
(3)创建spring的配置文件
1)位置:classPath下(可选择和src同级创建source folder文件夹,在这个文件夹下创建xml配置文件:spring Bean Configuration file)
2)配置文件命名:applicationContext;
3)配置xml文件
a.引入约束:beans;
b.注册bean(声明bean):为需要创建的对象配置bean结点和其他相关属性。
(4)测试:
1)通过new ClassPathXmlApplicationContext(“applicationContext.xml”)创建工厂;
2)再通过工厂的getBean()方法获取对象。
2、使用静态工厂创建对象(了解)
步骤:
(1)定义静态工厂;
(2)在工厂中创建一个静态的get方法返回创建好的对象;
(3)在spring的配置文件中注册bean:
1)id:指向spring容器中创建的这个唯一的实例;
2)bean的class:指向工厂的权限定名;
3)bean的factory-method:指向工厂中的get方法。
3、使用实例工厂创建对象(了解)
步骤:
(1)定义实例工厂;
(**2)在工厂中创建一个非静态的get方法**返回对象;
(3)在spring的配置文件中创建bean;
1)首先创建工厂,配置工厂的bean;
a.id:指向工厂唯一的id;
b.class:指向工厂的权限定名;
2)配置业务对象:
a.id指向spring容器中创建的这个唯一的实例;
b.factory-bean:指向工厂的id;
c.factory-method:指向工厂的get方法;
二、bean标签常用属性的设置
1、id
给实例对象取一个名字,通过这个名字来标识一个对象,该属性值不能包含特殊符号,一般使用接口名或者类名首字母小写;
2、name(不推荐使用)
功能和id一样,但是可以包含特殊符号,是为了整合struts框架遗留的,现在基本不用;
3、class
4、lazy-init
(1)意义:是否懒加载,值为:true或false;
(2)默认:默认为false,表示当加载配置文件的时候,所有声明在Spring配置文件中bean都立即加载(调用效率高);
5、scope
(1)意义:用于配置spring bean的作用域
(2)值:
1)singleton:表示是单例的,无论从容器中获取多少次们都是同一个对象;
· 2)prototype:原型,多例的,每一次从容器中获取对象,都会创建一个新的对象;
3)request:在一个request范围内,每一次获取的都是同一个对象;
4)session:在一个session范围内,每一次获取的都是同一个对象;
(3)默认值:默认为singleton,单例
(4)注意:如果一个bean配置为多例,那么立即加载则会失效,将会自动使用懒加载的策略;
6、init-method
(1)初始化的方式,创建完对象后立即调用,做一些初始化的准备工作
(2)这个方法是由spring调用,而不是开发者自己调用;
7、destory-method
销毁方法,在spring的容器销毁之前,调用该方法,做一些清理工作(只在单例情况下生效)。
想要执行销毁方法,需要手动销毁容器:context.closed();
8、factory-bean
9、factory-method
使用静态工厂或者实例工厂创建对象时:其值为工厂中获取实例的方法的名称。
三、spring中bean的生命周期
(1)spring调用构造器创建对象;
(2)执行初始化方法;
(3)等着被业务调用;
(4)在容器销毁之前,执行destroy方法;
(5)销毁容器。
四、依赖注入(Dependency Injection,简称DI)
1、定义
(1)依赖:一个对象完成业务功能,需要依赖另一个对象,比如service需要依赖dao;
(2)注入:获取该对象时,给他所依赖的引用对象赋值(实例化)。
2、依赖注入的两种方式
(1)使用set方法注入属性(重点,必须掌握,最常用)
1)在xml文件中配置要创建的对象的bean结点;
id为该对象唯一的id;
class为该对象所属类的权限定名;
2)在xml文件该bean的节点下配置property结点;
3)name属性:对应Java bean中的属性名;
3)value属性:基本数据类型的值,采用value属性配置;
4)ref属性:引用其他对象,其值采用ref属性配置,其值指向引用的对象的唯一的id;
注意:使用set方法注入属性时,务必保证Java
bean有相应的set方法。
(2)使用有参构造函数注入属性
1)在Java bean中设置有参构造函数;
2)在xml文件中配置要创建的对象的bean结点;
3)在xml文件该bean的节点下配置constructor-arg结点,constructor-arg结点下的name属性、value属性、ref属性同property结点中的属性;
注意:使用有参构造函数注入属性,务必保证Java bean有对应的有参构造函数,声明了有参构造函数之后,务必声明一个无参构造函数。
(3)使用P名称空间赋值注入依赖
1)引入p名称空间赋值约束;
2)在bean的结点的属性中进行赋值;
语法:①简单类型(基本数据类型+字符串):
②引用数据类型:
注意:这种命名方式不需要property属性,只需在bean结点添加属性或者依赖即可。
(4)spring的el表达式赋值
spring3以后提供了spring的el表达式方式注入属性;
语法:
1)基本类型:
注意:value值得数据类型为string时,需要添加引号。
2)引用类型:
3、多种数据类型的依赖注入(set方式注入)
(1)基本数据类型
(2)字符串类型
(3)POJO类型
(4)数组
1)在property节点下添加
2)在
3)代码示例:
<property name="intArr">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
(5)List集合
1)在property节点下添加结点,property中的name为list集合的名称;
2)在结点下添加多个
3)如果list中为对象,则在value中嵌入bean结点;
4)代码示例(同数组):
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
(6)Map容器
1)在property节点下添加
<property name="map">
<map>
<entry key="key1" value="value1"></entry>
<entry key="key2" value-ref="car2"></entry>
<entry key="key3">
<--!嵌入的bean结点-->
<bean class="com.cdsxt.model.Car">
<property name="brand" value="car4"></property>
<property name="price" value="99"></property>
</bean>
</entry>
</map>
</property>
(7)Set集合
1)在property节点下添加
2)在
3)如果值为对象,则在value中嵌入bean结点;
4)如果对象为上下文中已配置的bean,则添加结点;
5)代码示例:
<property name="set">
<set>
<value>set1</value>
<value>set2</value>
<value>10</value>
<ref bean="car5" />
</set>
</property>
(8)Properties集合
1)在property节点下添加
2)在< props >结点下添加多个
3)代码示例:
<property name="properties">
<props>
<prop key="key1">p1</prop>
<prop key="key2">p2</prop>
<prop key="key3">p3</prop>
<prop key="key4">p4</prop>
</props>
</property>
4、依赖注入(DI)和控制反转的(IOC)区别
(1)IOC(Inversion of Control):控制反转,是将对象的创建与调用分离;
(2)DI(Dependency Injection):依赖注入,维护bean与bean之间的关系;
(3)DI是建立在IOC的基础之上;
(4)不严谨的说DI和IOC是同一个概念,只不过站的角度不一样。
五、注解配置IOC和DI
基本步骤:
1、导入jar包
commons-logging、core、expression、context、beans、aop
2、引入约束
3、定义业务类添加注解
搭建项目基本结构,添加相应注解:
(1)需要创建对象的类上:@Component
约定:1)dao层:@Repository;
2)service层:@Service;
3)Controller层:@Controller;
(2)维护的引用类型上:@Autowired或者@Resource;
1**)@Autowired(由spring提供):
按照类型进行bean的装配(依赖关系的维护);
要求:依赖对象必须存在,如果需要允许为null,设置@Autowired(requied=false);如果想要使用名称装配,可以设置@Autowired@Qualifier(“name”);
2)@Resource(由j2EE**提供):
①有name属性时
按name属性给定的字符串到容器中查找是否有一个bean是这个名字:
如果找到,就赋值;
没有找到,抛异常:NoSuchBeanDedinitionException;
②没有name属性时
首先按照成员变量的属性名进行装配:
如果找到,就赋值;
如果没有找到,则再按照类型进行装配。
(3)基本数据类型赋值:@Value(value=”值”);
(4)其他几个注解
1)懒加载(lazy-init)的注解:@Lazy(value=””);
2)作用域(scope):@Scope(value=“”);
3)初始化方法(init-method):@PostConstructor(value=“”);
4)销毁方法(destroy-method):@PreDestroy(value=“”);
4、创建spring配置文件
(1)引入约束;
beans、context;
(2)配置包扫描
指定包路经,spring会递归扫描该包下的所有类,如果该包上有注解,则会创建相应的对象;
5、测试
六、AOP基础理论知识
1、什么是AOP
AOP:Aspect Oriented Program,面向切面编程;
2、优点
利用AOP可以将业务的各个部分进行隔离,从而使业务逻辑各个部分之间的耦合度降低,提高代码的复用性,同时提高开发效率;
3、AOP专业名词
(1)target:目标类;
(2)joinpoint:连接点,指所有可能想要增强的方法(织入通知的方法),理论上大部分方法都是连接点;
比如UserDao中的增删该查等方法,都是连接点;
(3)pointcut:切入点,已经被增强的方法(已经织入通知的方法);是从一系列连接点上筛选出的符合预期的连接点,比如,UserDao中的所有方法都是连接点,但是只需给增删改三个方法添加日志,那么增删改就是切入点,查则为连接点。
(4)advice:通知,增强的方法,比如日志、事务等,通知是一个方法;
(5)aspect:切面,通知所在的类叫切面,指advice和pointcut的结合;
(6)weaving:织入,将advice应用到目标对象来创建新的代理对象的过程;
(7)切入点表达式(方法签名):expression=“execution(
com.chen.dao.delet(..))”。
切入点表达式支持通配符:
1)括号中第一个 表示:任意的返回值;
2)括号中delete 表示:以delete开头的所有方法;
3)括号中的 .. :表示方法签名;
4、AOP应用场景
5、xml方式配置AOP
(1)导入jar包
core、context、expression、beans、commons-loging、aop、spring-aspect、aopalliance、aspectjweaver;
(2)定义业务层
(3)定义切面
(4)创建spring的配置文件
1)导入约束
2)配置bean
3)配置aop
①确定切点:需要确定在哪些方法上需要做增强;
②确定切面:一个项目中可能会有多个切面
③确定要使用切面中的哪个通知:一个切面中可能会有多个通知;
④确定通知执行的时机:
前置通知、后置通知、返回通知、异常通知、环绕通知。
⑤切入点表达式
expression=“execution( 包名+类名+方法签名)”
注意:..
表示方法参数列表;支持通配符。
常用写法:
com.sxt.service.UserService.addUser(..)
com.sxt.service.UserService.(..)
com.sxt.service.UserService.add(..)
com.sxt.service.UserService.do(..)
com.sxt.service..do(..)
com.sxt.service.Impl.(..)
配置文件示例:
<aop:config >
<!—确定切点:
注意:expression为切入点表达式。
-->
<aop:pointcut expression=”execution(* 包名+类名+方法签名)” id=”切点的唯一id”>
<!—确定切面
注意:before:表示通知执行时机,可换成:after、aftrer-returning、after-throwing、around。
method:为通知的方法名,确定执行当前切面的哪一个通知;
-->
<aop:aspect ref=”aspect”> //ref指向切面在spring容器中唯一的id;
<aop:before method="通知" pointcut-ref="切点的唯一标识符"/>
</aop:aspect>
</aop:config>
(5)测试
注意:当有接口时,spring默认使用jdk动态代理;没有接口时默认使用cglib代理,如果想要强制使用cglib代理,则可以在配置文件中开启。如下:
在配置文件中开启cglib代理:<aop:aspectj-autoproxy proxy-target-class=”true”></aop:aspectj-autoproxy”>