1.Spring简介
-Spring是Java的框架之一
-官网:https://spring.io/
-配置文件都是放到WebContent下,而且需要手动添加
2.IDEA创建Spring项目及结构体系
-File-->New Project --> 选择Spring即可
-lib:jar包目录
-Test:测试用例模块,需要自己编写测试用例
-Core Container
$ Spring的核心底层和容器,是Web和Data Access的基础,管理所有 的Java类。
$ core:提供框架的组成部分,包括控制反转(Ioc)和依赖注入(DI)功能。
$ beans:是BeanFactory,可以把配置和代码依赖从实际编码中解耦,通过Spring进行管理。
$ context:上下文模块,建立在core和beans的基础上,包括事件传播、资源加载等。
$ expression:表达语言,用在运行时查询和操作对象。
-Data Access/Integration
$ 数据库访问,集成,主要用于数据库的、XML等数据的访问和框架集成。
$ JDBC,Java连接数据库和访问数据库。
$ ORM,Java对象和XML数据库的隐射关系API
$ JMS,消息处理。
$ Transactions,事务处理,用来控制数据访问的一致性、完整性。
事务:是最小的工作单位,不论成功与否都作为一个整体进行工作,如:转账,自己扣了100元对方就多100元。
-web
$ web模块 提供 web的基本功能和上下文的应用 。如:http请求、文件上传、Servlet监听等等。
$ web-MVC,实现前后端解耦的一种设计模型,通过第三方模板引擎实现后端数据在页面的展示。
$ servlet,前后端请求时,是基于Http的Servlet实现的。
$ socket,用于web应用程序中的socket连接
-AOP
$ AOP,面向切面编程,允许定义方法拦截器和切入点对代码进行解耦,减少代码入侵。
$ Aspects,集成 AspectJ,一个功能强大且成熟的面向切面编程(AOP)框架。
$ Instrumentation,一般以应用服务器的监测。
3.Spring的配置文件:applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean>
</bean>
</beans>
4.Spring Bean
-Spring的bean其实就是java的实例,只是不需要new了,只需要Spring来创建即可。
-当Spring启动的时候就会将bean注册或加载进容器,然后在Spring容器中统一管理。
-只有在Spring容器中的bean才具备上下文的能力,才能被访问到Spring的框架和整合的框架。
-bean的定义和使用
既然bean是Java的实例,就需要先创建Java的类
然后直接在bean标签写Java类相应的属性和方法即可。
直接在配置文件中定义bean即可。
-通过ClassPathXmlApplicationContext使用bean
package com.youhui;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* User:youHui
*/
public class Spring1 {
public void printResult(){
System.out.println("this is SpringContent");
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
//获取bean
Spring1 s = (Spring1)context.getBean("spring1");
//使用
s.printResult();
}
}
<?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后只有在项目运行时才被注入到容器-->
<bean id="spring1" class="com.youhui.Spring1"></bean>
</beans>
5.bean加载原理和声明周期
-加载原理:Java的放射机制即:Class.forName("xxx")。
-bean的生命周期
bean的定义-->bean的初始化-->bean的使用-->bean的销毁。
6.bean的name属性
-id指定唯一的标识,在Spring的容器中必须唯一。
-name可以有多个名字,name="a1,a2,a3"。
-如果不指定id和name,默认从class="全路径"中获取。
-bean的依赖注入:通过<property name="javaClass" value="Data"></property>标签注入。
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* User:youHui
*/
public class Spring1 {
public void printSpringName(){
System.out.println("这是printSpringName()");
}
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring1 s = (Spring1)context.getBean("spring1-1");
s.printSpringName();
}
}
<bean name="spring1-1,spring2-2" class="com.youhui.s1.Spring1" />
7.bean的依赖注入DI
-B类在A类中作为属性存在
-通过property标签实现依赖注入
package com.youhui.s2;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* User:youHui
*/
public class Spring2 {
public User user;
public User getUser(){
user.userMethods();
return user;
}
public void setUser(){
this.user = user;
}
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring2 s = (Spring2)context.getBean("Spring2");
s.getUser();
}
}
package com.youhui.s2;
/**
* User:youHui
*/
public class User {
public void userMethods(){
System.out.println("这是user的方法");
}
}
<bean id="User" name="user" class="com.youhui.s2.User" />
<bean id="Spring2" name="spring2" class="com.youhui.s2.Spring2">
<!--两个类进行关联 reg:表示引用一个类-->
<property name="user" ref="User"></property>
</bean>
7.bean的init-method 和 destroy-method 属性
- init-method 实例化的时候回调方法
- destroy-method 销毁的时候回调方法
package com.youhui.s3;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* User:youHui
*/
public class Spring3 {
public void initSpring(){
System.out.println("这是init方法");
}
public void destroySpring(){
System.out.println("这是destroy方法");
}
public static void main(String[] args){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applictionContext.xml");
Spring3 s = (Spring3)context.getBean("Spring3");
//关闭注册
context.registerShutdownHook();
}
}
<bean id="Spring3" class="com.youhui.s3.Spring3" init-method="initSpring" destroy-method="destroySpring"/>
8.bean的autowire 属性
-autowire属性:可以实现自动注入eg:autowire = "byType|byName"
-在bean标签中加上autowire就可以不用加property标签,它会自动注入
package com.youhui.s4;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* User:youHui
*/
public class Spring4 {
public User4 user4;
public User4 getUser4(){
return user4;
}
public void setUser4(){
this.user4 = user4;
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring4 s = (Spring4)context.getBean("Spring4");
s.user4.printUser();
}
}
package com.youhui.s4;
/**
* User:youHui
*/
public class User4 {
public void printUser(){
System.out.println("printUser");
}
}
<bean id="user4" class="com.youhui.s4.User4" />
<bean id="Spring4" class="com.youhui.s4.Spring4" autowire="byName"></bean>
9.bean的lazy-init属性
- lazy-init表示是否懒加载: true/false
package com.youhui.s5;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* User:youHui
*/
public class Spring5 {
public void initSpring5(){
System.out.println("this is initSpring5");
}
public void destroySpring5(){
System.out.println("this is destroySpring5");
}
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
<bean lazy-init="true" id="Spring4" name="Spring4" class="com.youhui.s5.Spring5" init-method="initSpring5" destroy-method="destroySpring5" />
10.bean的 scope 属性
-scope表示bean的作用范围
-singleton,单例模式,在bean缓存中只有一个
-prototype,多例模式,每次实例化都会实例化一个新的对象
11.bean的depends-on属性
-depends-on表示bean对其他bean的依赖关系,被依赖的bean需要先实例化,常用于bean的加载顺序的设定
12.Sprin的注解
-注解说明:现在开发基本上都是用注解了,applicationContext.xml配置文件的方式,
不能用了,频繁的定义bean太麻烦,因此以上配置文件用来了解即可。
-注解都是@+...的形式,eg:@autowire
-Spring注解和bean在Spring容器中的本质是一样的。
-Java注解(可以理解为是一种标识,如@Override:标识重写父类函数):
$ Java注解,提供的是一种程序类型设置数据的方法。
$ Java中的类、方法、变量、参数等都可以加注解。
$ Java注解自动生成SQL
package com.youhui.s6;
/**
* User:youHui
*/
@MyTable(name="u_user")
public class User {
//用户的三个字段
@MyColumn(name="id")
public int id;
@MyColumn(name="user_name")
public String username;
@MyColumn(name="age")
public int age;
}
package com.youhui.s6;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* User:youHui
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface MyColumn {
//字段名字
String name();
int value() default 0;
}
package com.youhui.s6;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* User:youHui
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyTable {
//数据表的名称
String name();
}
JDBCtest实现类:
package com.youhui.s6;
import java.lang.reflect.Field;
/**
* User:youHui
*/
public class JDBCTest {
public void insert(User user) throws Exception{
//获取表名称的注解
MyTable myTable = user.getClass().getAnnotation(MyTable.class);
String tabName = myTable.name();
//获取属性
Field[] fields = user.getClass().getFields();
String[] columns = new String[fields.length];
String[] values = new String[fields.length];
for(int i = 0;i < fields.length; i++){
MyColumn myColumn = fields[i].getAnnotation(MyColumn.class);
columns[i] = myColumn.name();
fields[i].get(user);
values[i] = fields[i].get(user).toString();
}
//生成SQL
StringBuilder sb = new StringBuilder("INSERT INTO"+tabName);
sb.append("("
+String.join(",",columns)
+") VALUES ("
+String.join(",",values)
+")"
);
System.out.println(sb);
}
public static void main(String[] args) {
User user = new User();
user.id = 1;
user.username = "张三";
user.age = 18;
//把数据插入到数据库中
JDBCTest jdbc = new JDBCTest();
try {
jdbc.insert(user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
13.Spring常用注解
-@Component("name"):用于标注普通的组件
-@Service("name"):用于标注业务逻辑,常用于Service层
-@Repository("name"):用于标注Dao层的数据持久化类
-@Scope(value=ConfigurableBeanFactory.COPE_PROTOTYPE)
$ Scope注解可以用来定义@Component标注的作用范围以及@Bean所标记的类的作用范围
-@DependsOn:可以配置Spring IoC容器在初始化一个Bean之前,先初始化Bean对象
-@Bean:函数的注解,返回值是一个新的Bean,表示新的Bean放到Spring容器中管理
-@Autowired:自动注入(DI)
-@Qualifier:限定名
-配置注解:
$ @Configuration:创建、配置一个spring容器
$ @ComponentScan:扫描注解类的注解
$ @ImportResource:引入其他配置文件,eg:@ImportResource("classpath:applicationContext.xml)
14.Spring AOP(即面向切面编程)
-一些概念:AOP、IoC(控制反转)、DI(依赖注入)
-AOP:是一种编程思想,切面:就是把多条业务线进行统一拦截做一些操作,从而形成的面,称切面。常用于:验证事务等。
-Spring AOP的配置
$ 引入jar包:aspectjweaver-1.8.10.jar
通过maven下载,搜:org.aspectj:aspectjweaver:1.8.10
也可以直接拷贝到lib中即可
$ 在application配置文件中加入xmlns:aop的xsd文件
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
$ applicationContext.xml中添加Aspect注解
<aop:aspectj-autoproxy proxy-target-class="true" />
15.Spring JDBC(Java数据库的连接)
-访问数据库的发展史
$ 最初需要自己手写JDBC
$ 后来使用Spring JDBC Template
$ 现在直接使用MyBatis框架
-手写JDBC
$ 引入数据库驱动程序jar包
$ 创建连接
package com.youhui.s7;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
/**
* User:youHui
*/
public class JDBCTest {
public static void main(String[] args) {
//加载驱动程序
try{
Class.forName("com.mysql.jdbc.Driver");
//数据库地址
String url = "jdbc:mysql://127.0.0.1:3306/book?characterEncoding=UTF-8";
//创建连接
Connection conn = DriverManager.getConnection(url,"root","root");
//SQL语句
String sql = "SELECT name FROM bookList";
//执行SQL语句
PreparedStatement statement = conn.prepareStatement(sql);
ResultSet set = statement.executeQuery();
while(set.next()){
System.out.println(set.getString(1));
}
//关闭连接
conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
16.Spring事务
-事务数据库中的概念:保证事务范围中的操作的一致性,全部成功或者全部失败。
-对数据库的单次操作(如:执行一条查询语句),就是最小事务。
-Spring事务的配置
$ 把一下内容拷贝到applicationContext.xml配置文件中
xmlns:tx="http://www.springframework.org/schema/tx"
以下配置放到xsi:schemaLocation中:
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
$ 事务管理配置
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
$ 配置事务的注解支持
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
17.Spring的测试用例
- 用来测试程序中的bug
- 手写测试用例
$ 导入包:junit-4.13.2.jar、hamcrest-2.2.jar
$ 在类上面加注解:@RunWith(SpringJUnit4ClassRunner.class)
$ 让测试用例加载spring配置文件:在类上面加注解:@ContextConfiguration({"classpath:applicationContext.xml"})
$ 在方法上面加 @Test 即可运行,不需要写主函数
package com.youhui.s8;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* User:youHui
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext.xml"})
public class Spring8 {
@Test //表示运行这个测试用例
public void printTest(){
System.out.println("this is printTest");
}
}