简介
Spring是Java EE编程领域的一个轻量级开源框架,该框架由一个叫Rod Johnson的程序员在 2002 年最早提出并随后创建,是为了解决企业级编程开发中的复杂性,实现敏捷开发的应用型框架 。Spring是一个开源容器框架,它集成各类型的工具,通过核心的Bean factory实现了底层的类的实例化和生命周期的管理。在整个框架中,各类型的功能被抽象成一个个的 Bean,这样就可以实现各种功能的管理,包括动态加载和切面编程。
Spring 就是一个轻量级的控制反转IOC和面向切面AOP的框架。
参考网站:
第一个Spring程序
创建一个maven项目
在pom.xml里导入依赖
1 2 3 4 5 6 7
| <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.6.RELEASE</version> </dependency> </dependencies>
|
创建一个类,比如我的HelloSpring类
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class HelloSpring { private String str; public String getStr(){ return str; } public void setStr(String str){ this.str = str; } @Override public String toString(){ return "{"+"str="+str+"}"; } }
|
在resources资源目录下配置applicationContext.xml
1 2 3 4 5 6 7 8 9 10 11
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id ="hello" class="com.chen.pojo.HelloSpring"> <property name="str" value=" Hello Spring"/> </bean> </beans>
|
测试类
1 2 3 4 5 6 7 8
| public class test01 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloSpring hello = context.getBean("hello",HelloSpring.class); System.out.println(hello.toString()); } }
|
Spring配置
别名
为创建的对象起别名,即为bean的id起别名
1
| <alias name="userserviceimpl" alias="user"></alias>
|
Bean
以上面的例子为例
1 2 3
| <bean id ="hello" class="com.chen.pojo.HelloSpring" name ="user,u1,u2"> <property name="str" value=" Hello Spring"/> </bean>
|
id为bean的标识符,即创建的对象名
class为对象对所对应的类名,注意是全限定名
name为别名,与alias差不多,可以起多个别名
property属性,为str这个参数赋值
import
合并xml配置文件。
依赖注入
依赖注入DI,具体说法可参考我之前写的有关IOC的文章
构造器注入
使用无参构造器创建对象
这种是Spring默认的创建对象的方式,在上述的Spring例子当中,HelloSpring的bean创建对象是用的无参构造器,若没有了无参构造器就会报错。
使用有参构造器创建对象
下标
1 2 3 4
| <bean id ="hello" class="com.chen.pojo.HelloSpring"> <constructor-arg index="0" value="helloSpring">; </bean>
|
类型
1 2 3 4
| <bean id ="hello" class="com.chen.pojo.HelloSpring"> <constructor-arg type="String" value="helloSpring">; </bean>
|
参数名
1 2 3 4
| <bean id ="hello" class="com.chen.pojo.HelloSpring"> <constructor-arg name="str" value="helloSpring">; </bean>
|
当bean被注册,加载到该配置文件,即使没有用到这个对象,也会生成。
Set方式注入
注入到对象中的属性,例如我的这个例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| public class Student { private String name; private Address address; private String[] books; private List<String> hobbies; private Map<String,String> card; private Set<String> games; private String ll; private Properties info; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", address=" + address + ", books=" + Arrays.toString(books) + ", hobbies=" + hobbies + ", card=" + card + ", games=" + games + ", ll='" + ll + '\'' + ", info=" + info + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public List<String> getHobbies() { return hobbies; } public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; } public Map<String, String> getCard() { return card; } public void setCard(Map<String, String> card) { this.card = card; } public Set<String> getGames() { return games; } public void setGames(Set<String> games) { this.games = games; } public String getLl() { return ll; } public void setLl(String ll) { this.ll = ll; } public Properties getInfo() { return info; } public void setInfo(Properties info) { this.info = info; } }
|
基本数据类型和String类型的注入
1 2 3
| <bean id="student" class="com.chen.pojo.Student"> <property name="name" value="student1"/> </bean>
|
引用类型的注入
1 2 3 4 5
| <bean id="adress" class="com.chen.pojo.Address"/> <bean id="student" class="com.chen.pojo.Student"> <property name="address" ref="adress"/> </bean>
|
数组的注入
1 2 3 4 5 6 7 8 9 10
| <bean id="student" class="com.chen.pojo.Student"> <property name="books"> <array> <value>a</value> <value>b</value> <value>c</value> <value>d</value> </array> </property> </bean>
|
List的注入
1 2 3 4 5 6 7 8
| <bean id="student" class="com.chen.pojo.Student"> <property name="hobbies"> <list> <value>music</value> <value>game</value> </list> </property> </bean>
|
Map的注入
1 2 3 4 5 6 7 8 9 10
| <bean id="student" class="com.chen.pojo.Student"> <property name="card"> <map> <entry key="1" value="a"/> <entry key="2" value="b"/> <entry key="3" value="c"/> <entry key="4" value="d"/> </map> </property> </bean>
|
Set的注入
1 2 3 4 5 6 7 8 9
| <bean id="student" class="com.chen.pojo.Student"> <property name="games"> <set> <value>kkk</value> <value>sss</value> <value>www</value> </set> </property> </bean>
|
null注入即空值注入
1 2 3 4 5
| <bean id="student" class="com.chen.pojo.Student"> <property name="ll"> <null/> </property> </bean>
|
Properties的注入
1 2 3 4 5 6 7 8
| <bean id="student" class="com.chen.pojo.Student"> <property name="info"> <props> <prop key="s">111</prop> <prop key="ww">333</prop> </props> </property> </bean>
|
注入的时候是通过你创建的set方法注入的,所以创建类的时候要写上set方法,养成习惯get方法也写上,为了更好的测试,就重写toString方法
拓展方式注入
P命名空间的注入
想要使用这种方法,先得在bean元素上加入p的命名空间,如下
1 2 3 4 5 6 7 8 9
| <?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
|
1
| <bean id="adress" class="com.chen.pojo.Address" p:address="this" p:a="18"/>
|
这种方式的注入是简单类型的注入,引用类型也可以,类似set注入,但能支持注入的类型少。
C命名空间注入
类似P命名空间,用前需要在bean元素上加入c的命名空间,如下
1 2 3 4 5 6 7 8 9 10
| <?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
|
1
| <bean id="adress" class="com.chen.pojo.Address" c:address="this" c:a="18"/>
|
这种方式的是通过构造器注入的,想要注入的属性就要存在这样的有参构造器。注意因为创建对象要用到无参构造器,所以不要漏写。
Bean的作用域(Scope)
单例模式
单例模式是指每次创建的bean都是同一个,这也是Spring默认的模式,比如
1 2 3 4 5
| <bean id = "address" class="com.chen.pojo.Address" scope="singleton"> <property name="a" value="1"/> <property name="address" value="s"/> </bean>
|
1 2 3 4 5 6 7 8 9 10
| public class test01 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Address address1 = context.getBean("address",Address.class); Address address2 = context.getBean("address",Address.class); System.out.println(address1.hashCode()); System.out.println(address2.hashCode()); } }
|
单例模式表示bean只会创建一个对象,每次get的都是同一个
原型模式
原型模式就和单例模式相反,每次get的都不是同一个。
1 2 3 4 5
| <bean id = "address" class="com.chen.pojo.Address" scope="prototype"> <property name="a" value="1"/> <property name="address" value="s"/> </bean>
|
1 2 3 4 5 6 7 8 9 10
| public class test01 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Address address1 = context.getBean("address",Address.class); Address address2 = context.getBean("address",Address.class); System.out.println(address1.hashCode()); System.out.println(address2.hashCode()); } }
|
原型模式表示每次创建的bean都不是同一个对象
Spring的自动装配
首先为了更好的测试,先创建两个类,之后的例子就从这两个类中测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class User { private String name; private Score score; public Score getScore() { return score1; } public void setScore(Score score) { this.score1 = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Score { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Score{" + "name='" + name + '\'' + '}'; } }
|
自动装配是从bean的autowire属性配置的。
byName的自动装配
byName的自动装配是从类中寻找具有相同属性的类,然后装配到bean里,比如在User中有Score类创建的对象,而且有set方法,所以可以自动将Score的对象装配到User类里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="score" class="com.chen.pojo.Score"> <property name="name" value="课程"/> </bean> <bean id="user" class="com.chen.pojo.User" autowire="byName"> <property name="name" value="张三"/> </bean>
</beans>
|
1 2 3 4 5 6 7
| public class test01 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = context.getBean("user", User.class); System.out.println(user.getScore()); } }
|
是按照User类里的Set方法寻找的,比如Score类在bean里注册的id为score,那User类里就要有setScore这个set方法,将set去掉,首字母小写,然后与id对应一致才能找的到,这是byName的自动装配。
byTypee的自动装配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="score11" class="com.chen.pojo.Score"> <property name="name" value="课程"/> </bean> <bean id="user" class="com.chen.pojo.User" autowire="byType"> <property name="name" value="张三"/> </bean>
</beans>
|
1 2 3 4 5 6 7
| public class test01 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = context.getBean("user", User.class); System.out.println(user.getScore()); } }
|
byType是寻找类里属性类型相同的bean,所以不关id的事情了,id都可以省略。弊端就是当一个类注册了两个bean的时候,byType不知道选择哪一个就会报错。
用注解实现自动装配
首先想用注解先要导入context约束和注解的支持,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?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.xsd "> <context:annotation-config/> </beans>
|
@Autowired注解
这个注解可以放在属性名上,也可以放在set方法上,放在属性名上,连set方法都可以不用写,当然是引用的类里要有set方法。
1 2 3 4 5
| <bean class="com.chen.pojo.Score"> <property name="name" value="课程"/> </bean> <bean id="user" class="com.chen.pojo.User" > </bean>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class User { private String name; @Autowired private Score score; public Score getScore() { return score1; } public void setScore1(Score score) { this.score1 = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
|
@Autowired里面有个属性是required,默认为true,表示不能为空值,可以手动关闭@Autowired(required = falser)。
@Autowired是通过byType模式来寻找的,若是一个类有多个bean才会选择用byName来自动装配。
要是多个bean的id都不符合byName的时候,就需要使用@Qualifier(value=”id”)来配合使用,value的值为哪个bean的id,就使用哪个bean自动装配。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <bean id="score1" class="com.chen.pojo.Score"> <property name="name" value="课程1"/> </bean> <bean id="score2" class="com.chen.pojo.Score"> <property name="name" value="课程2"/> </bean> <bean id="score3" class="com.chen.pojo.Score"> <property name="name" value="课程3"/> </bean> <bean id="user" class="com.chen.pojo.User" > </bean>
|
使用注解开发
想使用注解来进行开发,先要确定好自己的配置。
导入aop的包(之前导入的依赖包含了aop的包),注解使用不了就确定一下有没有aop的包导入
导入context的约束,开启支持注解
还要指定扫描的包,是包里的注解生效,比如例子的包
1
| <context:component-scan base-package="com.chen.pojo"/>
|
注册bean
在xml中注册bean
1 2
| <bean id="score" class="com.chen.pojo.Score"> </bean>
|
使用注解来注册bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Component public class Score { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Score{" + "name='" + name + '\'' + '}'; } }
|
使用了@Component注解,会将这个类装配。可以指定id,在没有指定id的时候,这个类的bean的id就是当前类名首字母小写的字符串。
指定id可以这样写到@Component(“xxx”)。
@Component 的三个衍生注解,在 web 开发中,会按照 mvc 三层架构分层。
- dao 层@Repository
- service 层@Service
- web 层@Controller
这四个注解功能都是一样的。
属性注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Component public class Score { @Value("lll") private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Score{" + "name='" + name + '\'' + '}'; } }
|
属性注入可以使用@Value(“”)的注解,当然简单的才会使用注解,复杂一点的注入还是xml配置注解好一点。
自动装配
就是之前得用注解实现自动装配
作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Component @Scope("prototype") public class Score {
@Value("chen") private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Score{" + "name='" + name + '\'' + '}'; } }
|
作用域可以使用@Scope(““),里面是模式,常用的就是singleton和prototype,默认也是singleton。
使用Java的方式配置Spring
先看demo吧
用户类
1 2 3 4 5 6 7 8 9 10 11
| public class User { @Value("chen") private String name;
public String getName() { return name; } public void setName(String name) { this.name = name; } }
|
Java配置类
1 2 3 4 5 6 7
| @Configuration public class pojoconfig { @Bean public User getUser(){ return new User(); } }
|
测试类
1 2 3 4 5 6 7
| public class test01 { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(pojoconfig.class); User user = context.getBean("getUser",User.class); System.out.println(user.getName()); } }
|
一个个分析吧。
用户类没什么区别,主要是Java配置类。
@Configuration表示这个类是个配置类,类似于xml。
@Bean表示bean的配置。方法名就相当于id。
AOP
关于AOP的介绍就放到另一篇文章里。AOP
这里就讲讲spring中AOP的具体实现。
首先要导入依赖,和aop的约束
1 2 3 4 5
| <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.5</version> </dependency>
|
1 2 3 4 5 6 7 8 9 10
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
|
使用Spring的接口来实现
首先定义好 接口,并创建好真实对象,即接口实现类
1 2 3 4 5 6
| public interface userService { void add(); void delete(); void update(); void select(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class userServiceImpl implements userService{ public void add() { System.out.println("增加了一个用户"); } public void delete() { System.out.println("删除了一个用户"); } public void update() { System.out.println("修改了一个用户"); } public void select() { System.out.println("查询了一个用户"); } }
|
定义一个功能类
1 2 3 4 5
| public class log implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了"); } }
|
method表示目标对象的方法,objects表示参数,target目标对象。实验的例子是使用MethodBeforeAdvice这个接口,即在目标方法调用之前调用的Advice通知。
MethodBeforeAdvice 前置通知
AfterReturningAdvice 后置通知,有返回值
MethodInterceptor 环绕通知
ThrowsAdvice 异常通知
然后就要在applicationContext.xml里配置了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServiceImpl" class="com.chen.pojo.userServiceImpl"></bean> <bean id ="log" class="com.chen.pojo.log"></bean>
<aop:config> <aop:pointcut id="p" expression="execution(* com.chen.pojo.userServiceImpl.*(..))"/> <aop:advisor advice-ref="log" pointcut-ref="p"></aop:advisor> </aop:config>
</beans>
|
这里来解析一下execution的表达式。 com.chen.pojo.userServiceImpl.. .*(..)
- execution()为表达式主体,里面为表达式
- 第一个 表示返回的类型,表示任意类型的返回值
- 表示需要拦截的包,即真实对象所在的位置
- 包名后面的,,*表示当前包以及子包
- 第二个 表示方法,表示所有方法
- (..)表示方法可以有任意的参数
测试类
1 2 3 4 5 6 7 8 9 10 11
| public class test01 { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); userService userService = context.getBean("userServiceImpl", userService.class); userService.add(); userService.delete(); userService.update(); userService.select(); } }
|
注意这里的用的是接口而不是实现类。
使用自定义类来实现
定义接口和实现类,和上述一样
定义一个通知类
1 2 3 4 5
| public class log { public void before(){ System.out.println("方法执行"); } }
|
配置xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="userServiceImpl" class="com.chen.pojo.userServiceImpl"></bean> <bean id = "log" class="com.chen.pojo.log"/> <aop:config> <aop:aspect ref="log"> <aop:pointcut id="point" expression="execution(* com.chen.pojo.userServiceImpl.*(..))"/> <aop:before method="before" pointcut-ref="point"/> </aop:aspect>
</aop:config>
</beans>
|
这种方法还是不够好,简单的插入可以使用这种。
使用注解来实现
使用注解来实现跟自定义类实现其实差不多。
定义接口和实现类,和上述一样
定义通知类
1 2 3 4 5 6 7 8 9
| @Aspect public class log { @Before("execution(* com.chen.pojo.userServiceImpl.*(..))") public void before(){ System.out.println("方法执行"); } }
|
然后把这个类注册到spring里,并开启注解支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userServiceImpl" class="com.chen.pojo.userServiceImpl"></bean> <bean id ="log" class="com.chen.pojo.log"/> <aop:aspectj-autoproxy/>
</beans>
|
开启注解支持还能设置动态代理模式
值为false表示使用JDK动态代理(默认),为true表示使用cglib动态代理
Spring与Mybatis整合
导入依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.chen</groupId> <artifactId>spring-study</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>spring-01</module> </modules>
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.6.RELEASE</version> </dependency>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.9.RELEASE</version> </dependency>
<dependency> <groupId>org.assertj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency>
</dependencies>
<build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource>
<resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
</project>
|
配置spring的xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="dateSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dateSource"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:...."/> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> </beans>
|
这个xml是可以代替原来Mybatis的配置文件,以后使用可以直接通过import导入就好了。
事务
导入约束
用Spring事务时先导入约束,如下
1 2 3 4 5 6 7 8 9 10 11
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
|
配置事务通知
1 2 3 4 5 6 7 8 9 10
| <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="select" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
|
配置事务切入
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="select" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="txp" expression="execution(* com.chen.mapper..*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txp"/> </aop:config>
|
后话
spring终于结束了,说实话spring相对Mybatis还是简单很多的,但细节还是挺多的,学了几天,前面又忘了,还是得多看看细节才行。emm,我的笔记也比较水,还有一些细节还没写出来,看得云里雾里得也挺正常,大概就看看复习一下就好了。end。下个框架见。
还没写完—-