一、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)基本数据类型

value=“值”;

(2)字符串类型

value=”值”;

(3)POJO类型

ref=”引用对象的唯一id”;

(4)数组

1)在property节点下添加结点,property中的name为数组的名称;
2)在结点下添加多个结点,在value节点中添加数组的每个值;
3)代码示例:

  1. <property name="intArr">
  2. <array>
  3. <value>1</value>
  4. <value>2</value>
  5. <value>3</value>
  6. </array>
  7. </property>

(5)List集合

1)在property节点下添加结点,property中的name为list集合的名称;
2)在结点下添加多个结点,在value节点中添加list的每个值;
3)如果list中为对象,则在value中嵌入bean结点;
4)代码示例(同数组):

  1. <property name="list">
  2. <list>
  3. <value>list1</value>
  4. <value>list2</value>
  5. <value>list3</value>
  6. </list>
  7. </property>

(6)Map容器

1)在property节点下添加结点,property中的name为map集合的名称;
2)在结点下添加多个结点,在entry节点上添加key属性和value属性,分别对应map的键值对;
3)如果值为对象,则在value中嵌入bean结点;
4)代码示例:

  1. <property name="map">
  2. <map>
  3. <entry key="key1" value="value1"></entry>
  4. <entry key="key2" value-ref="car2"></entry>
  5. <entry key="key3">
  6. <--!嵌入的bean结点-->
  7. <bean class="com.cdsxt.model.Car">
  8. <property name="brand" value="car4"></property>
  9. <property name="price" value="99"></property>
  10. </bean>
  11. </entry>
  12. </map>
  13. </property>

(7)Set集合

1)在property节点下添加结点,property中的name为set集合的名称;
2)在结点下添加多个结点,在value节点中添加集合的每一个值;
3)如果值为对象,则在value中嵌入bean结点;
4)如果对象为上下文中已配置的bean,则添加结点
5)代码示例:

  1. <property name="set">
  2. <set>
  3. <value>set1</value>
  4. <value>set2</value>
  5. <value>10</value>
  6. <ref bean="car5" />
  7. </set>
  8. </property>

(8)Properties集合
1)在property节点下添加结点,property中的name为properties集合的名称;
2)在< props >结点下添加多个结点,在prop节点上添加键key的值,在prop结点中添加对应键的值;
3)代码示例:

  1. <property name="properties">
  2. <props>
  3. <prop key="key1">p1</prop>
  4. <prop key="key2">p2</prop>
  5. <prop key="key3">p3</prop>
  6. <prop key="key4">p4</prop>
  7. </props>
  8. </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、引入约束

beans、context

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)导入约束

beans、aop;

2)配置bean

xml方式;

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.(..)
配置文件示例:

  1. <aop:config >
  2. <!—确定切点:
  3. 注意:expression为切入点表达式。
  4. -->
  5. <aop:pointcut expression=”execution(* 包名+类名+方法签名)” id=”切点的唯一id”>
  6. <!—确定切面
  7. 注意:before:表示通知执行时机,可换成:afteraftrer-returningafter-throwingaround
  8. method:为通知的方法名,确定执行当前切面的哪一个通知;
  9. -->
  10. <aop:aspect ref=”aspect”> //ref指向切面在spring容器中唯一的id;
  11. <aop:before method="通知" pointcut-ref="切点的唯一标识符"/>
  12. </aop:aspect>
  13. </aop:config>

(5)测试

注意:当有接口时,spring默认使用jdk动态代理;没有接口时默认使用cglib代理,如果想要强制使用cglib代理,则可以在配置文件中开启。如下:
在配置文件中开启cglib代理:
<aop:aspectj-autoproxy proxy-target-class=”true”></aop:aspectj-autoproxy”>