Spring学习笔记
什么是spring
spring发展历程
spring的优势
spring体系结构
spring快速入门
spring开发步骤
解释:以前开发都是直接new一个对象,但是耦合度太高了。怎么降低耦合度?可以利用反射(动态加载)来实现。可以参阅韩顺平老师的反射课程。链接: 反射.
快速入门
导入坐标
编写Dao接口和实现类
Dao接口
public interface UserDao {
public void save();
}
实现类
public class UserDaoImpl implements UserDao{
@Override
public void save() {
}
}
创建spring配置文件
- 配置文件名称一般为application.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">
</beans>
在容器中加入bean
<?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="userDao" class="com.zhw.spring5.dao.impl.UserDaoImpl"></bean>
</beans>
从容器中获取bean实例
public static void main(String[] args) {
//加载app容器
ApplicationContext app = new ClassPathXmlApplicationContext("application.xml");
//获取userDao实例
UserDao userDao = app.getBean(UserDao.class);
userDao.save();
}
spring配置文件
bean标签的配置
id
id为在容器中的唯一性标识,用户获取该bean
class
class为该类的全限定名
scope
singleton(单例模式):单例的,无论在什么地方获取该bean都是同一个对象
测试单例模式
@Test
public void test01() {
UserDao userDao1 = app.getBean(UserDao.class);
UserDao userDao2 = app.getBean(UserDao.class);
System.out.println(userDao1);//结果@9225652
System.out.println(userDao2);//结果@9225652
}
测试原型模式
@Test
public void test01() {
UserDao userDao1 = app.getBean(UserDao.class);
UserDao userDao2 = app.getBean(UserDao.class);
System.out.println(userDao1);//结果@19bb07ed
System.out.println(userDao2);//结果@10e41621
}
容器中bean的创建时机
容器会调用bean的无参构造方法来创建bean
单例的bean随着容器的创建而创建,随着容器的销毁而销毁
bean的声明周期方法
只有单实例的bean有声明周期方法
1.在UserDaoImpl中添加初始化方法和销毁方法
public class UserDaoImpl implements UserDao {
String name ;
//无参构造,容器创建bean是会调用该方法
public UserDaoImpl() {
System.out.println("UserDaoImpl被创建了");
name = "zhw";
}
//初始化方法,当创建该bean完成后会调用改方法
public void initMethod(){
System.out.println("初始化方法");
}
//销毁方法
public void destoryMethod(){
System.out.println("销毁方法");
}
@Override
public void save() {
System.out.println("save running...");
}
@Override
public String getName() {
return this.name;
}
}
2.在配置文件中设置初始化方法和销毁方法
<bean id="userDao" class="com.zhw.spring5.dao.impl.UserDaoImpl" init-method="initMethod" destroy-method="destoryMethod"></bean>
3.测试
public class Test01 {
public static ApplicationContext app;
@BeforeClass
public static void beforeClass(){
app = new ClassPathXmlApplicationContext("application.xml");
}
/**
* 测试声明周期方法
*/
@Test
public void test02() {
UserDao userDao1 = app.getBean(UserDao.class);
String name = userDao1.getName();
System.out.println(name);
//手动关闭
((ClassPathXmlApplicationContext)app).close();
}
}
打印结果:
UserDaoImpl被创建了
初始化方法
bean的实例化3种方式
spring容器默认是调用bean的无参构造方法来创建实例,可以设置为不用无参构造的方式来创建实例。
无参构造实例化
工厂静态方法实例化
1.创建工厂对象
/**
* 可以批量注册bean
*/
public class StaticFactory {
//可以自己指定调用哪些方法,只要返回对应的对象就可以了。
public static UserDao getUserDao(){
UserDaoImpl userDao = new UserDaoImpl("zsh");
userDao.getName();
userDao.setName("zhenghaowen");
return userDao;
}
}
配置xml配置文件
factory-method:工厂的哪一个方法
<bean id="userDao" class="com.zhw.spring5.factory.StaticFactory" factory-method="getUserDao" init-method=""></bean>
总结:
1在静态方法中,只要最会返回的是要获取的对象就可以
2.bean同样是单实例的
工厂实例方法实例化
1.创建工厂
public class DynamicFactory {
public UserDao getUserDao(){
UserDaoImpl userDao = new UserDaoImpl();
return userDao;
}
}
2.配置xml配置文件
1.先把工厂给注册进来
<bean id="factory" class="com.zhw.spring5.factory.DynamicFactory"></bean>
2.factory-bean:指定哪一个工厂 factory-method:工厂的哪一个方法
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
3.测试
//静态方法实例化
@Test
public void test04() {
UserDao userDao = app.getBean(UserDao.class);
String name = userDao.getName();
System.out.println(name);
}
打印结果:
zhenghaowen
依赖注入
不用依赖注入的方式
1.controller层
public class UserController {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("application.xml");
UserService userService = app.getBean(UserService.class);
userService.save();
}
2.service层
public class UserServiceImpl implements UserService {
@Override
public void save() {
//service调用dao层需要先获取dao层
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("application.xml");
UserDao userDao = app.getBean(UserDao.class);
userDao.save();
}
}
3.dao层
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("dao save running...");
}
}
4.问题:
- 每次都要从spring容器中获取要使用的对象,那么能不能直接在容器中将一些bean组合,将一些bean注入到需要使用该bean的内部,这样我们只需直接获取bean就行
bean的依赖注入分析
依赖注入概念
Bean的依赖注入方式
两种方法无论哪一种都需要定义成员变量
userServiceImpl要注入userDao和Test的值
public class UserServiceImpl implements UserService {
private UserDao userDao;
private String test;
public void setTest(String test) {
this.test = test;
}
public void setUserDao(UserDao userDao) {
System.out.println("UserServiceImpl有参构造1被创建...");
this.userDao = userDao;
}
public UserServiceImpl() {
System.out.println("UserServiceImpl无参构造被创建...");
}
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
public UserServiceImpl(UserDao userDao, String test) {
System.out.println("UserServiceImpl有参构造2被创建...");
this.userDao = userDao;
this.test = test;
}
public UserDao getUserDao() {
return userDao;
}
public String getTest() {
return test;
}
@Override
public void save() {
userDao.save();
}
}
构造方法注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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="userService" class="com.zhw.spring5.service.impl.UserServiceImpl">
<!-- <constructor-arg name="userDao" ref="userDao"/>-->
<constructor-arg index="0" type="com.zhw.spring5.dao.UserDao" ref="userDao"/>
<constructor-arg index="1" type="java.lang.String" value="我是测试"/>
</bean>
</beans>
- 使用这种方式再spring容器在创建容器的时候,不会在调用无参后构造方法创建实例,而是调用对应的构造方法创建实例对象
- spring会找到对应的参数的构造器,,如果没有会报错
//构造方法注入
@Test
public void test05() {
UserServiceImpl userService = (UserServiceImpl)app.getBean(UserService.class);
System.out.println(userService.getTest());
}
结果:
UserDaoImpl被创建了
UserServiceImpl有参构造2被创建...
我是测试
set方法注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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="userDao" class="com.zhw.spring5.dao.impl.UserDaoImpl"></bean>
<!-- set方法注入-->
<bean id="userService" class="com.zhw.spring5.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
<property name="test" value="我是测试!!"></property>
</bean>
</beans>
p命名空间
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
1.添加p命名空间
xmlns:p="http://www.springframework.org/schema/p"
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">
<!-- p命名空间-->
2.p:test注入普通值,p:userDao-ref注入引用类型
<bean id="userService" class="com.zhw.spring5.service.impl.UserServiceImpl" p:test="我是测试" p:userDao-ref="userDao"/>
</beans>
bean的依赖注入类型
package com.zhw.spring5.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
//普通字符串类型
private String name;
private Integer age;
private String addr;
private String phone;
//list集合类型
private List<String> hobby;
//引用对象类型
private Book book;
//map集合类型
private Map<String,Book> map;
}
package com.zhw.spring5.entities;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private String bookName;
}
依赖注入类型
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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="book" class="com.zhw.spring5.entities.Book" p:bookName="小王子"></bean>
<bean id="book1" class="com.zhw.spring5.entities.Book" p:bookName="月亮与六便士"></bean>
<bean id="book2" class="com.zhw.spring5.entities.Book" p:bookName="复活"></bean>
<bean id="book3" class="com.zhw.spring5.entities.Book" p:bookName="第七天"></bean>
<bean id="student" class="com.zhw.spring5.entities.Student">
<constructor-arg type="java.lang.String" name="name" index="0" value="张国荣"/>
<constructor-arg type="java.lang.Integer" name="age" index="1" value="21"/>
<constructor-arg type="java.lang.String" name="addr" index="2" value="中国"/>
<constructor-arg type="java.lang.String" name="phone" index="3" value="10000000000"/>
<constructor-arg type="java.util.List" name="hobby" index="4">
<list>
<value>唱歌</value>
<value>跳舞</value>
<value>电影</value>
</list>
</constructor-arg>
<constructor-arg type="com.zhw.spring5.entities.Book" index="5" name="book" ref="book"/>
<constructor-arg type="java.util.Map" index="6" name="map" >
<map>
<entry key="book1" value-ref="book1"/>
<entry key="book2" value-ref="book2"/>
<entry key="book3" value-ref="book3"/>
</map>
</constructor-arg>
</bean>
</beans>
测试
//bean的注入类型
@Test
public void test06() {
Student stu = app.getBean(Student.class);
System.out.println(stu.toString());
}
结果
Student(
name=张国荣,
age=21,
addr=中国,
phone=10000000000,
hobby=[唱歌, 跳舞, 电影],
book=Book(bookName=小王子),
map={
book1=Book(bookName=月亮与六便士),
book2=Book(bookName=复活),
book3=Book(bookName=第七天)
}
)
引入其他配置文件(分模块开发)
1.application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
1.引入application-student.xml配置文件
<import resource="application-student.xml"/>
</beans>
2.application-student.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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="book" class="com.zhw.spring5.entities.Book" p:bookName="小王子"></bean>
<bean id="book1" class="com.zhw.spring5.entities.Book" p:bookName="月亮与六便士"></bean>
<bean id="book2" class="com.zhw.spring5.entities.Book" p:bookName="复活"></bean>
<bean id="book3" class="com.zhw.spring5.entities.Book" p:bookName="第七天"></bean>
<bean id="student1" class="com.zhw.spring5.entities.Student">
<constructor-arg type="java.lang.String" name="name" index="0" value="张国荣"/>
<constructor-arg type="java.lang.Integer" name="age" index="1" value="21"/>
<constructor-arg type="java.lang.String" name="addr" index="2" value="中国"/>
<constructor-arg type="java.lang.String" name="phone" index="3" value="10000000000"/>
<constructor-arg type="java.util.List" name="hobby" index="4">
<list>
<value>唱歌</value>
<value>跳舞</value>
<value>电影</value>
</list>
</constructor-arg>
<constructor-arg type="com.zhw.spring5.entities.Book" index="5" name="book" ref="book"/>
<constructor-arg type="java.util.Map" index="6" name="map" >
<map>
<entry key="book1" value-ref="book1"/>
<entry key="book2" value-ref="book2"/>
<entry key="book3" value-ref="book3"/>
</map>
</constructor-arg>
</bean>
<bean id="student2" class="com.zhw.spring5.entities.Student">
<constructor-arg type="java.lang.String" name="name" index="0" value="张国荣"/>
<constructor-arg type="java.lang.Integer" name="age" index="1" value="21"/>
<constructor-arg type="java.lang.String" name="addr" index="2" value="中国"/>
<constructor-arg type="java.lang.String" name="phone" index="3" value="10000000000"/>
<constructor-arg type="java.util.List" name="hobby" index="4">
<list>
<value>唱歌</value>
<value>跳舞</value>
<value>电影</value>
</list>
</constructor-arg>
<constructor-arg type="com.zhw.spring5.entities.Book" index="5" name="book" ref="book"/>
<constructor-arg type="java.util.Map" index="6" name="map" >
<map>
<entry key="book1" value-ref="book1"/>
<entry key="book2" value-ref="book2"/>
<entry key="book3" value-ref="book3"/>
</map>
</constructor-arg>
</bean>
</beans>
测试
//bean的注入类型
@Test
public void test07() {
//顶级父类接受
BeanFactory app = new ClassPathXmlApplicationContext("application.xml");
Student student = app.getBean("student1",Student.class);
System.out.println(student);
}
结果
Student(
name=张国荣,
age=21,
addr=中国,
phone=10000000000,
hobby=[唱歌, 跳舞, 电影],
book=Book(bookName=小王子),
map={
book1=Book(bookName=月亮与六便士),
book2=Book(bookName=复活),
book3=Book(bookName=第七天)
}
)
spring相应的API
ApplicationContext的继承体系
ApplicationContext的实现类
ClasspathXmlApplicationContext
从类的根路径下加载配置文件,推荐使用
FileSystemXmlApplicationContext
从磁盘路径上加载配置文件,配置文件可以磁盘的任意位置
public static ApplicationContext app;
@BeforeClass
public static void beforeClass(){
// app = new ClassPathXmlApplicationContext("application.xml");
app = new FileSystemXmlApplicationContext("G:\\spring5_workspace\\springdemo01\\src\\main\\resources\\application.xml");
}
AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建spring容器
getBean()使用
//getBean的使用
Object student1 = app.getBean("student1");
//当容器中有多个该类型时会报错,不知道找哪一个
Student bean1 = app.getBean(Student.class);
Student student2 = app.getBean("student1", Student.class);
spring配置数据源
数据源(连接池)的作用
数据源开发步骤
手动创建c3p0数据源
@Test
//1.测试手动创建c3p0数据源
public void test1() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//配置数据源
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Shanghai");
dataSource.setUser("root");
dataSource.setPassword("123456");
dataSource.setMaxPoolSize(20);
//获取连接
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
手动创建druid数据源
@Test
//2.测试手动创建c3p0数据源
public void test2() throws Exception {
DruidDataSource dataSource = new DruidDataSource();
//配置数据源
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Shanghai");
dataSource.setUsername("root");
dataSource.setPassword("123456");
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
//归还至数据源
connection.close();
}
抽取jdbc.properties
1.在resources目录下创建jdbc。properties配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Shanghai
jdbc.user=root
jdbc.password=123456
2.读取并使用
@Test
//3.抽取配置到文件
public void test3() throws Exception {
//1.读取配置文件
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
//2.获取配置
String driver = rb.getString("jdbc.driver");
String url = rb.getString("jdbc.url");
String user = rb.getString("jdbc.user");
String password = rb.getString("jdbc.password");
DruidDataSource dataSource = new DruidDataSource();
//配置数据源
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
DruidPooledConnection connection = dataSource.getConnection();
System.out.println(connection);
//归还至数据源
connection.close();
}
spring管理数据源
1.引入maven坐标
<?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
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.13</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2.配置applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
<!--配置c3p0数据源,注入依赖-->
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Shanghai"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
</bean>
</beans>
3.测试数据源
@Test
//4.测试从ioc容器中获取数据源
public void test4() throws Exception {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = app.getBean("c3p0",DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
4.打印结果
com.mchange.v2.c3p0.impl.NewProxyConnection@2f953efd
spring加载properties配置文件
1.在resources下创建jdbc.properties配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?serverTimezone=Asia/Shanghai
jdbc.user=root
jdbc.password=123456
2.引入context命名空间和约束,配置数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--加载外部的properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--配置c3p0数据源-->
<bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置druid数据源-->
<bean id="druid" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
spring注解开发
spring原始注解
准备环境
1.user
package cn.zhw.annotation.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private String name;
private Integer age;
}
2.userDao
package cn.zhw.annotation.dao.impl;
import cn.zhw.annotation.dao.UserDao;
import org.springframework.stereotype.Repository;
//作为dao层加入到容器
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("userDao saveing...");
}
}
3.userService
package cn.zhw.annotation.service.impl;
import cn.zhw.annotation.dao.UserDao;
import cn.zhw.annotation.service.UserService;
import org.springframework.stereotype.Service;
//作为service层加入到容器中
@Service("userService")
public class UserServiceImpl implements UserService {
//依赖注入userDao
@Autowired
private UserDao userDao;
@Override
public void save() {
userDao.save();
System.out.println("userService saveing...");
}
}
当配置了注解后需要告诉配置文件,去扫描标注了注解的类,并将该类加入到容器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
1.添加命名空间
xmlns:context="http://www.springframework.org/schema/context"
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
2.添加约束
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置组件扫描-->
<context:component-scan base-package="cn.zhw.annotation"/>
</beans>
总结:
1.当用注解依赖注入时,可以不用set和构造器来注入
2.需要在配置文件中指定组件扫描
用配置类代替配置文件
配置类等同于一个xml配置文件
1.创建配置类
package cn.zhw.annotation.config;
import cn.zhw.annotation.dao.UserDao;
import cn.zhw.annotation.dao.impl.UserDaoImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
//扫描cn.zhw.annotation
@ComponentScan(basePackages = {"cn.zhw.annotation"}) //等同于xml配置文件的<context:component-scan base-package="cn.zhw.annotation"/>
public class ApplicationContext {
}
2.使用
@Test
//3.用配置类代替配置文件
public void test03(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(ApplicationContext.class);
String[] beanDefinitionNames = app.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
3.打印结果
//spring自己加入的
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
//自己加入的
applicationContext
userDao
userService
spring原始注解详解
关于spring的注解可以看: spring注解开发.
- @Autowired
- 按照类型注入
- @Resource
- 先按照名字注入,找不到按照类型注入
- @Autowired + @Quailif
- 用于当在容器中找到多个相同类型的bean时,找到对应名字的bean
spring新注解
package cn.zhw.annotation.config;
import org.springframework.context.annotation.*;
@Configuration //说明该类是一个配置类,自己本身也是一个组件,也会加到ioc容器中
@ComponentScan(basePackages = {"cn.zhw.annotation"})//组件扫描
@Import(ApplicationContextStudent.class)//引入另一个配置类
public class ApplicationContext {
}
@Configuration
public class ApplicationContextStudent {
@Bean //将该对象加到ioc容器中
public StudentServiceImpl StudentServiceImpl(){
return new StudentServiceImpl();
}
}
spring整合junit
原始的问题
解决思路
spring集成junit步骤
1.导入坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.9.RELEASE</version> //该版本,依赖junit4.12及以上版本
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version> //注意junit的版本要4.12及以上,不然会报错
<scope>test</scope>
</dependency>
2.配置类
package cn.zhw.annotation.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
@Configuration
@ComponentScan(basePackages = {"cn.zhw.annotation"})
@Import(ApplicationContextStudent.class)
@PropertySource(value = {"classpath:jdbc.properties"}) //记载resources目录下的jdbc.properties到运行时变量
public class ApplicationContext {
@Value("${jdbc.driver}")
private String dirver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.user}")
private String user;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource DataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(dirver);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setMaxActive(10);
return dataSource;
}
}
3.测试代码
package com.zhw.test;
import cn.zhw.annotation.config.ApplicationContext;
import cn.zhw.annotation.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
//使用spring提供的内核测试
@RunWith(SpringJUnit4ClassRunner.class)
//告诉容器配置文件的位置
//@ContextConfiguration("classpath:applicationContext.xml")
@ContextConfiguration(classes = {ApplicationContext.class})
public class SpringJunitTest {
//注入容器中的bean
@Autowired
private UserService userService;
@Autowired
private DataSource dataSource;
@Test
public void test01(){
userService.save();
}
@Test
public void test02() throws SQLException {
Connection connection = dataSource.getConnection();
while (true){
System.out.println(connection);
connection.close();
}
}
}
3.结果
userDao saveing...
userService saveing...