- 基本概念:起源,优点
- 基本使用
- 整合mybatis框架
Spring: 是一个开源的轻量级容器框架(包含并管理应用对象的配置和生命周期,javabean的创建方式可配置为prototype 或singleton ) 提倡的编程思想是:控制反转(IoC), 面向切面(AOP)
Spring 的起源:Rod Johnson 在2002年编著的《Expert one on one J2EE design and development》一书中,对Java EE 系统框架臃肿、低效、脱离现实的种种现状提出了质疑,并因此开发出轻便小巧的interface21框架,也即spring的前身。
part1: 基本使用 (使用xml文件:管理对象创建)
(开发工具: idea + maven )
第一步: 创建java module, 添加maven支持, 配置pom.xml添加jar包依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
第二步: 创建包 a, 创建 【接口 + 实现子类】, 在resources目录下:配置xml 使得spring管理对象的创建
//接口
public interface HelloI {
void say();
}
//接口--实现类
public class HelloImpl implements HelloI {
private String name;
//构造
public HelloImpl( String b, int a){ System.out.println("String b ,int a"); }
public HelloImpl(int a, String b){ System.out.println("int a, String b "); }
public HelloImpl(Integer a, String b){ System.out.println("Integer a, String b ");}
public HelloImpl(String name) { this.name = name; }
public HelloImpl() { }
//一般方法
public void say() { System.out.println("hello "+ name); }
//get,set
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
在resources目录下:配置自定义的beans.xml ( 使得spring管理对象的创建 )
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="helloImpl" class="a.HelloImpl">
<property name="name" value="tom"/>
</bean>
<bean id="helloImpl2" class="a.HelloImpl" scope="prototype">
<constructor-arg type="int" value="1" ></constructor-arg>
<constructor-arg type="java.lang.String" value="aa" ></constructor-arg>
<property name="name" value="tom"/>
</bean>
<bean id="helloImpl3" class="a.HelloImpl" scope="prototype">
<constructor-arg type="java.lang.String" value="aa" index="0"></constructor-arg>
<constructor-arg type="int" value="1" index="1" ></constructor-arg>
<property name="name" value="tom"/>
</bean>
</beans>
第三步: 创建测试类, 验证对象的创建
@org.junit.Test
public void t(){
//创建: 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
HelloI h= (HelloI) context.getBean("helloImpl");
h.say();
}
part2: 以注解的方式创建对象
第一步: 修改接口实现类的定义---添加@Repository注解
@Repository
public class HelloImpl implements HelloI {...}
第二步: 修改自定义的beans.xml文件, 添加--扫描注解的支持
<!--自动扫描-->
<context:component-scan base-package="类所在的包名"></context:component-scan>
第三步: 创建测试类,验证对象的创建
@org.junit.Test
public void t2(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//getBean: 对象名必须为类名的小写,如HelloImpl-->helloImpl
HelloI h= (HelloI) context.getBean("helloImpl");
h.say();
}
part3: 面向切面编程
( 三种配置方式: 加强版代理模式,使用<aop:config>标签配置)
第一步:创建包: aop, 新建方法增强类
//自定义方法如何增强:代理模式的'handler'角色
//后置增强
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterReturningTest implements AfterReturningAdvice {
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("after....");
}
}
//环绕增强
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundAdviceTest implements MethodInterceptor {
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
long start=System.nanoTime();
System.out.println("--------方法 begin");
Object res = methodInvocation.proceed();
System.out.println("--------方法 end ---time="+ (System.nanoTime()-start));
return res;
}
}
//前置增强
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class BeforeMethodTest implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("before....");
}
}
//异常增强
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
public class ThrowsAdviceTest implements ThrowsAdvice {
public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
System.out.println("error....");
ex.printStackTrace();
}
}
第二步: 创建xml文件, 使得spring管理对象的装配---创建自定义的aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--方法增强处理器: 前置通知-->
<bean id="beforeAdvice" class="aop.BeforeMethodTest"></bean>
<bean id="errorAdvice" class="aop.ThrowsAdviceTest"></bean>
<bean id="aroundAdvice" class="aop.AroundAdviceTest"></bean>
<bean id="afterAdvice" class="aop.AfterReturningTest"></bean>
<!--接口实例: 目标对象-->
<bean id="helloImpl" class="a.HelloImpl">
<property name="name" value="tom"/>
</bean>
<!--代理: 创建proxy对象-->
<bean id="proxyBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--接口[]-->
<property name="proxyInterfaces">
<list>
<value>a.HelloI</value>
</list>
</property>
<!--处理器: 方法增强者-->
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
<value>errorAdvice</value>
<value>aroundAdvice</value>
<value>afterAdvice</value>
</list>
</property>
<!--接口实例对象-->
<property name="target" ref="helloImpl"></property>
</bean>
</beans>
第三步: 创建测试类, 验证aop
@Test
public void t(){
//创建: 上下文
ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml");
HelloI h= (HelloI) context.getBean("proxyBean");
h.say();
}
结果如下:
part4: spring整合mybatis
pom.xml管理类的依赖: c3p0数据源, spring的jar包, mybatis的jar包, mybatis-spring的jar包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!--mysql连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.41</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
类的结构关系
//javabean
public class User {
//字段
private int id;
private int age;
private String name;
private String sex;
//构造
public User() {}
public User(int age, String name, String sex) {
this.age = age;
this.name = name;
this.sex = sex;
this.id=id;
}
@Override
public String toString() {
return "User{" +
"age=" + age +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", id=" + id ;
}
//get,set...
}
//dao层实现类: UserDaoImpl
import a.User;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@Repository("dao")
public class UserDaoImpl extends SqlSessionDaoSupport {
public int insert(User user){
int res = getSqlSession().insert("users.insert",user);
return res;
}
@Resource
@Override
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
}
//service层实现类
import a.User;
import dao.UserDaoImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userServiceImpl")
public class UserServiceImpl {
@Autowired
UserDaoImpl dao;
public int insert(User user){
return dao.insert(user);
}
}
spring配置文件: beans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd ">
<!--自动扫描: 注解所在的包, 使得spring自动注入对象-->
<context:component-scan base-package="service, dao, a"></context:component-scan>
<!-- 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="insert*" isolation="DEFAULT" propagation="REQUIRED" />
<tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" />
<tx:method name="delete*" isolation="DEFAULT" propagation="REQUIRED" />
<tx:method name="select*" isolation="DEFAULT" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..*Service.*(..))" />
</aop:config>
<!-- 事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--连接池: c3p0-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db"></property>
<property name="user" value="root"></property>
<property name="password" value="daitoue"></property>
<property name="initialPoolSize" value="3"></property>
<property name="maxPoolSize" value="10"></property>
</bean>
<!--session工厂-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
</beans>
mybatis配置文件: mybatis-config.xml, UserMapper.xml
<!-- 文件: mybatis-config.xml -->
<?xml version = "1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--别名-->
<typeAliases>
<typeAlias type="a.User" alias="_user" />
</typeAliases>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
<!-- 文件: UserMapper.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 定义名字空间 -->
<mapper namespace="users">
<!-- 定义insert语句 ,获得生成的id字段-->
<insert id="insert">
insert into users2(name,sex) values(#{name},#{sex})
</insert>
<update id="update" >
update users2 set name=#{name}, sex=#{sex} where id=#{id}
</update>
<select id="selectById" resultType="a.User" >
select * from users2 where id=#{id}
</select>
<delete id="delete">
delete from users2 where id=#{id}
</delete>
</mapper>
创建测试类: 验证sm
@org.junit.Test
public void t(){
//加载配置
ApplicationContext context= new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl service= (UserServiceImpl) context.getBean("userServiceImpl");
User user = new User(23,"test-ssm","boy");
int res = service.insert(user);
System.out.println(res);
}