一、准备工作
1.创建Maven的java项目。
2.导入java项目的依赖
<dependencies>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-core
</artifactId
>
<version>4.3.10.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-context
</artifactId
>
<version>4.3.10.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-beans
</artifactId
>
<version>4.3.10.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-expression
</artifactId
>
<version>4.3.7.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>commons
-logging
</groupId
>
<artifactId>commons
-logging
</artifactId
>
<version>1.1.2</version
>
</dependency
>
</dependencies
>
3.编写applicationContext.xml 文件
src->main->resources->applicationContext.xml
<?xml version
="1.0" encoding
="UTF-8"?>
<beans xmlns
:xsi
="http://www.w3.org/2001/XMLSchema-instance" xmlns
="http://www.springframework.org/schema/beans"
xsi
:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
</beans
>
二、使用spring创建bean对象
不需要再手动new对象
1.向applicationContext.xml配置文件中加入bean
<?xml version
="1.0" encoding
="UTF-8"?>
<beans xmlns
:xsi
="http://www.w3.org/2001/XMLSchema-instance" xmlns
="http://www.springframework.org/schema/beans"
xsi
:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">
<bean id
="stu" class="demo.bean.Student">
<property name
="name" value
="小明"></property
>
<property name
="age" value
="18"></property
>
</bean
>
</beans
>
2.通过spring的方式获取对象,只能通过空参构造创建
@Test
public void test2(){
ApplicationContext ac
= new ClassPathXmlApplicationContext("applicationContext.xml");
Student stu
= ac
.getBean("stu",Student
.class);
System
.out
.println(stu
.getId()+"\t"+stu
.getName()+"\t"+stu
.getAge());
stu
.sayHello();
}
3.spring创建对象是否单例
默认是单例,也可更改,加上scope属性
三、SpringIOC 讲解
IOC控制反转
* IOC Inversion of Control 控制反转。
*
* 控制反转就是只对象控制权的反转。
* 在没有使用IOC之前,对象的创建都是由应用程序来负责的(程序员在代码中自己new)
* 在使用了Spring(spring的IOC)后,对象的创建交给了spring(对象由spring负责创建)
* 这种对象的控制器由应用程序转到spring的现象就叫做控制反转。
DI依赖注入
依赖注入(Dependency Injection)
* 类与类的关系:
*
* 1 继承关系
class A extends B
* 2 关联关系
* class A{
* }
*
* class B{
* private A a
;
* }
*
* B类中的成员变量是A类型。 A类和B类是关联关系
*
* 3 依赖关系
*
* Class
C{
*
* }
*
* class D{
* public void fun(C c
){
* }
* }
*
* D类中的方法使用C类型。D类和C类就是依赖关系。D依赖C
*
要讲解的Spring中依赖注入的依赖是广义上的依赖。 只要A类中使用了B类,就说A类依赖B类型
依赖注入: 不使用spring之前,依赖的对象也是由应用程序来控制(自己new)
使用spring之后,依赖的对象靠spring来注入!!!
所以,依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,由spring来创建对象,实现对象之间的解耦。
spring的工厂
BeanFactory 和ApplicationContext的区别: 1.ApplicationContext是BeanFactory 的子接口,比BeanFactory 拥有更多功能。 2.创建对象的时机不同: ApplicationContext是加载完spring的配置文件后,就创建对象。 BeanFactory 是调用getBean时才创建对象。
四、属性注入
set注入
bean中必须有无参构造,属性有set方法
<bean id
="stu" class="demo.bean.Student" >
<property name
="name" value
="小明"></property
>
<property name
="age" value
="18"></property
>
</bean
>
构造器注入
bean中必须有有参构造,可以加入get方法获取属性值
<bean id
="car" class="demo.bean.Car">
<constructor
-arg name
="name" value
="宝马"></constructor
-arg
>
<constructor
-arg name
="color" value
="red"></constructor
-arg
>
</bean
>
复杂类型注入,属于set注入
private String
[] arr
;
private List list
;
private Set set
;
private Map map
;
private Properties prop
;
<bean id
="array" class="demo.bean.Array">
<!--数组
-->
<property name
="arr">
<array>
<value>arr1
</value
>
<value>arr2
</value
>
<value>arr3
</value
>
</array
>
</property
>
<!--list集合
-->
<property name
="list">
<list>
<value>list1
</value
>
<value>list2
</value
>
<value>list3
</value
>
</list
>
</property
>
<!--set集合
-->
<property name
="set">
<set>
<value>set1
</value
>
<value>set2
</value
>
<value>set3
</value
>
</set
>
</property
>
<!--map集合
-->
<property name
="map">
<map>
<entry key
="map1" value
="111"></entry
>
<entry key
="map2" value
="222"></entry
>
<entry key
="map3" value
="333"></entry
>
</map
>
</property
>
<!--Properties配置文件
-->
<property name
="prop">
<props>
<prop key
="prop1">111</prop
>
<prop key
="prop2">222</prop
>
<prop key
="prop3">333</prop
>
</props
>
</property
>
</bean
>
五、SpringAOP 讲解
面向切面编程Aspect Oriented Programming
AOP名词解释
目标(Target) 没有增强功能之前的代码(要被增强,要增加新功能) 切面(Aspect) 要增强的新功能(方法),放在切面中 织入(Weaving) 动词,把目标和切面切在一起的动作(把切面切入到目标中) 代理(Proxy) 目标和切面织到一起后形成的新对象(即具有目标的原有功能,有具体增强的新功能) 切入点(PointCut) 目标中所有可以被切面切的地方(一般是目标中的方法)
连接点(JoinPoint) 当切面真的来切这个切入点了,这个切入点就变成了连接点
通知(Advice) 告诉切面在哪里(在目标方法调用之前、目标方法调用之后、环绕、抛异常时)去切
添加依赖
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-aop
</artifactId
>
<version>4.3.10.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-aspects
</artifactId
>
<version>4.3.10.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.aspectj
</groupId
>
<artifactId>aspectjrt
</artifactId
>
<version>1.6.12</version
>
</dependency
>
<dependency>
<groupId>org
.aspectj
</groupId
>
<artifactId>aspectjweaver
</artifactId
>
<version>1.6.12</version
>
</dependency
>
<dependency>
<groupId>cglib
</groupId
>
<artifactId>cglib
</artifactId
>
<version>2.1_3
</version
>
</dependency
>
创建切面类
public class Aop {
public void method(){
System
.out
.println("切面。。。。。。");
}
}
配置切入
<bean id
="aop" class="demo.aspect.Aop"></bean
>
<!--配置切入
-->
<aop
:config
>
<!--切入点
-->
<aop
:pointcut id
="allservice" expression
="execution(* demo.service.StudentServiceImpl.*(..))"/>
<!--切面
-->
<aop
:aspect ref
="aop">
<aop
:before method
="method" pointcut
-ref
="allservice"></aop
:before
>
</aop
:aspect
>
</aop
:config
>
方法命名add*(…):所有以add开头的方法
效果
通知说明
Around通知较为特殊,需要在切面方法中放行目标方法 pjp.proceed();
<aop
:around method
="myAround" pointcut
-ref
="allServiceMethod"/>
放行目标方法
public void myAround(ProceedingJoinPoint pjp
){
System
.out
.println("around 环绕 ,在目标方式之前执行###");
try {
pjp
.proceed();
} catch (Throwable e
) {
e
.printStackTrace();
}
System
.out
.println("around 环绕 ,在目标方式之后执行####");
}
获取连接点
public class Aop {
public void method(JoinPoint jp
){
jp
.getArgs();
String name
= jp
.getSignature().getName();
}
六、spring整合JDBC
1.添加依赖
除了通用的IOC依赖,还有以下依赖
<!-- druid mysql
-->
<dependency>
<groupId>mysql
</groupId
>
<artifactId>mysql
-connector
-java
</artifactId
>
<version>5.1.45</version
>
</dependency
>
<dependency>
<groupId>com
.alibaba
</groupId
>
<artifactId>druid
</artifactId
>
<version>1.1.10</version
>
</dependency
>
<!-- spring
-jdbc spring
-tx
-->
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-jdbc
</artifactId
>
<version>4.3.10.RELEASE
</version
>
</dependency
>
<dependency>
<groupId>org
.springframework
</groupId
>
<artifactId>spring
-tx
</artifactId
>
<version>4.3.10.RELEASE
</version
>
</dependency
>
2.书写dao
public class AddUserImpl implements AddUser{
JdbcTemplate jt
;
public JdbcTemplate
getJt() {
return jt
;
}
public void setJt(JdbcTemplate jt
) {
this.jt
= jt
;
}
@Override
public int add(User user
) {
String sql
="insert into users values(null,?,?);";
int update
= jt
.update(sql
, user
.getUsername(), user
.getPassword());
return update
;
}
}
3.书写配置文件
<!--配置持久层操作对象
-->
<bean id
="jdbctemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name
="dataSource" ref
="ds"></property
>
</bean
>
<!--配置持久层
-->
<bean id
="userdao" class="demo.dao.AddUserImpl">
<property name
="jt" ref
="jdbctemplate"></property
>
</bean
>
<!--配置数据源
-->
<bean id
="ds" class="com.alibaba.druid.pool.DruidDataSource">
<property name
="url" value
="jdbc:mysql:///test"></property
>
<property name
="driverClassName" value
="com.mysql.jdbc.Driver"></property
>
<property name
="username" value
="root"></property
>
<property name
="password" value
="123456"></property
>
</bean
>
七、spring注解方式IOC开发
1.添加配置文件
<!--开启spring注解方式
-->
<context
:annotation
-config
></context
:annotation
-config
>
<!--设置扫描路径
-->
<!--spring会为扫描路径下所有添加了
@Component注解的类创建spring的bean
-->
<context
:component
-scan base
-package="demo"></context
:component
-scan
>
<!--开启AOP注解
-->
<aop
:aspectj
-autoproxy
></aop
:aspectj
-autoproxy
>
2.类上添加注解
@Component
@Scope("prototype")
public class Transaction {
@Autowired
private Car c
;
@Autowired
private Ship s
;
public Car
getC() {
return c
;
}
public void setC(Car c
) {
this.c
= c
;
}
public Ship
getS() {
return s
;
}
public void setS(Ship s
) {
this.s
= s
;
}
}
3.常用注解
@Component :添加了这个注解的类会被spring扫描当成 bean来处理 可以设置bean的id : @Component(“起名字bean的id”) 也可以不设置bean的id 默认就是类名首字母变小写
@Autowired : 自动装配(按类型) 问题:当多个类型符合时,将无法注入
解决:
@Scope(“prototype”) 更改单例为每次getBean创建新的对象
Spring还提供了以下几个注解来替代 @Component @Controller 一般加在控制层 @Service 一般加在业务层 @Repository 一般加在持久层 作用和@Component完全相同(可能会在以后的版本中有不同)
八、注解方式AOP开发
1.添加配置文件
<!-- 开启注解方式的aop
-->
<aop
:aspectj
-autoproxy
></aop
:aspectj
-autoproxy
>
2.配置切面注解
@Component
@Aspect
public class log {
@Pointcut("execution(* demo.service.*.*(..))")
public void anyMethod(){
}
@Before("execution(* demo.service.*.*(..))")
public void before(){
System
.out
.println("before............");
}
@After("execution(* demo.service.*.*(..))")
public void after(){
System
.out
.println("after............");
}
@AfterReturning("anyMethod()")
public void afterReturn(){
System
.out
.println("afterReturning............");
}
@Around("execution(* demo.service.*.*(..))")
public void around(ProceedingJoinPoint jp
){
System
.out
.println("around 1----------");
try {
jp
.proceed();
} catch (Throwable throwable
) {
throwable
.printStackTrace();
}
System
.out
.println("around 2------------");
}
}
3.切面注解的两种方式对比
方式一固定,一旦修改就都改变。 方式二较为灵活。
九、修改ApplicationContext对象
1.添加依赖
2.设置监听器
监听器ContextLoaderListener的init方法,随着服务器启动,servletContext的创建而执行,让servletContext加载context-param中的参数,加载xml,生成了ApplicationContext对象。
3.获取applicationContext对象
避免每次都new,一直使用servletContext中的ApplicationContext
十、spring事务
1.配置文件方式事务开发
配置事务管理器和切入点
<bean id
="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"></bean
>
<!-- 配置事务管理器
(切面
) 目标就是service
-->
<!-- spring针对不同的持久层提供了不同的事务管理器
(切面
) jdbc:DataSourceTransactionManager
-->
<!-- 事务管理器可以控制事务的提交和回滚 需要操作数据库 需要把dataSource注入给事务管理器
-->
<bean id
="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name
="dataSource" ref
="ds"></property
>
</bean
>
<!-- 定义事务的传播规则
-->
<tx
:advice id
="txAdvice" transaction
-manager
="dataSourceTransactionManager">
<tx
:attributes
>
<tx
:method name
="add*" propagation
="REQUIRED"/>
<tx
:method name
="modify*" propagation
="REQUIRED"/>
<tx
:method name
="remove*" propagation
="REQUIRED"/>
<tx
:method name
="zhuanzhang" propagation
="REQUIRED" no
-rollback
-for="java.lang.ArithmeticException" />
</tx
:attributes
>
</tx
:advice
>
<aop
:config
>
<aop
:pointcut id
="allServiceMethods" expression
="execution(* com.offcn.service.impl.*.*(..))"/>
<aop
:advisor advice
-ref
="txAdvice" pointcut
-ref
="allServiceMethods"></aop
:advisor
>
</aop
:config
>
2.事务的传播规则
3.回滚规则
默认情况下spring的事务管理是碰见异常就回滚 no-rollback-for:碰见这种异常不回滚,其他异常都回滚
4.注解方式事务开发
1.配置事务管理器,开启注解方式事务
<bean id
="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource"></bean
>
<!-- 注解方式的事务管理,事务管理器还是需要配置
-->
<bean id
="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name
="dataSource" ref
="ds"></property
>
</bean
>
<!--引入事务管理器
-->
<tx
:annotation
-driven transaction
-manager
="dataSourceTransactionManager" proxy
-target
-class="true"></tx
:annotation
-driven
>
2.代码 使用@Transactional注解: 可以加在类上,也可以加在方法
加在类上,这个类中的所有public修饰的方法都会被事务管理
加在方法上,就是这个具体的方法会被事务管理
@Service("accountService")
public class AccountServiceImpl implements AccountService {
@Transactional(propagation
= Propagation
.REQUIRED
)
public String
zhuanzhang(int outId
, int inId
, int money
) {
5.配置文件方式和注解方式比较
配置文件方式可以一次对指定的所有切入点添加事务。注解方式需要挨个在每个类上添加,如果类多的情况下,显然麻烦。