Spring---Spring专题(二)-
1、Spring配置数据源
1.1 数据源(连接池)的作用
-
数据源(连接池)是提高程序性能而出现的
-
事先实例化数据源,初始化部分链接资源
-
使用连接资源时从数据源中获取
-
使用完毕后将连接资源归还给数据源
常见的数据源:DBCP、C3P0、BoneCp、Druid等
开发步骤:
1、导入数据源的坐标和数据库驱动坐标
2、创建数据源对象
3、设置数据源的基本连接数据
4、使用数据源获取连接资源和归还连接资源
1.2 数据源的手动创建
1、导入mysql数据库驱动坐标、导入c3p0和druid的坐标
<dependencies> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>域名</version> </dependency> <!-- c3p0连接池--> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <!-- Druid连接池--> <dependency> <groupId>域名aba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency> <!-- junit单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>域名.2</version> <scope>test</scope> </dependency> </dependencies>
2、创建c3p0连接池
1 import 域名.域名oPooledDataSource; 2 import 域名; 3 4 import 域名ection; 5 6 public class DatasourceTest { 7 @Test 8 public void test1() throws Exception { 9 //创建数据源 10 ComboPooledDataSource dataSource = new ComboPooledDataSource(); 11 //数据库连接参数 12 域名riverClass("域名.Driver"); 13 域名dbcUrl("jdbc:mysql://localhost:3306/test"); 14 域名ser("root"); 15 域名assword("123"); 16 //获得连接对象 17 Connection conn = 域名onnection(); 18 域名tln(conn); 19 域名e(); 20 21 } 22 }
3、提取域名erties配置文件
域名er=域名.driver 域名=jdbc:mysql://localhost:3306/test 域名name=root 域名word=123
4.读取配置文件创建连接池
1 @Test 2 //测试手动创建c3p0数据源(加载properties配置文件) 3 public void testC3p0Properties() throws Exception { 4 //加载配置文件 域名erties 5 ResourceBundle rb = 域名undle("jdbc"); 6 ComboPooledDataSource dataSource = new ComboPooledDataSource(); 7 域名riverClass(域名tring("域名er")); 8 域名dbcUrl(域名tring("域名")); 9 域名ser(域名tring("域名name")); 10 域名assword(域名tring("域名word")); 11 Connection conn = 域名onnection(); 12 域名tln(conn); 13 域名e(); 14 }
1.3 Spring配置数据源
可以将DataSource的创建权交由Spring容器去完成
<bean id="dataSource" class="域名.域名oPooledDataSource"> <property name="driverClass" value="域名.driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property> <property name="user" value="root"></property> <property name="password" value="123"></property> </bean>
测试从容器中获取数据源
1 @Test 2 //spring容器产生数据对象 3 public void testSpringDataSource() throws Exception { 4 ApplicationContext app = new ClassPathXmlApplicationContext("域名"); 5 DataSource dataSource = 域名ean(域名s); 6 Connection conn = 域名onnection(); 7 域名tln(conn); 8 域名e(); 9 }
1.4 抽取jdbc配置文件
域名加载域名erties配置文件获得连接信息
引入context的命名空间和约束条件:
命名空间:
xmlns:context="http://域名/schema/context"
约束路径:
http://域名/schema/context http://域名/schema/context/spring-域名
加载外部的properties配置文件
<context:property-placeholder location="classpath:域名erties"/> <bean id="dataSource" class="域名.域名oPooledDataSource"> <property name="driverClass" value="${域名er}"/> <property name="jdbcUrl" value="${域名}"/> <property name="user" value="${域名name}"/> <property name="password" value="${域名word}"/> </bean>
2. Spring注解开发
2.1 Spring原始注解
Spring是请代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,从而提高开发效率。
Spring原始注解主要是替代<Bean>的配置
注解 | 说明 |
---|---|
@Component | 使用在类上,用于实例化Bean |
@Controller | 使用在web层类上,用于实例化Bean |
@Service | 使用在service层类上,用于实例化Bean |
@Repository | 使用在dao层类上,用于实例化Bean |
@Autowired | 使用在字段上,用于根据类型依赖注入 |
@Qualifier | 结合@Autowired一起使用,用于根据名称进行依赖注入 |
@Resource | 相当于@Autowired+@Qualifier,根据名称进行注入 |
@Value | 注入普通属性 |
@Scope | 标注Bean的作用范围 |
@PostConstruct | 实用在方法上标注,该方法是Bean的初始化方法 |
@PreDestroy | 使用在方法上标注,该方法是Bean的销毁方法 |
使用@Component或 @Repository标识UserDaoImpl进行实例化
1 //<bean id="userDao" class="域名.UserDaoImpl"></bean> 2 //@Component("userDao") 3 @Repository("userDao") 4 public class UserDaoImpl implements UserDao{ 5 6 public void save() { 7 域名tln("Save Running...."); 8 } 9 }
使用@Component或 @Service标识UserServiceImpl进行实例化
使用@Autowired或@Autowired+@Qualifier或@Resource进行userDao的注入
1 //<bean id="userService" class="域名域名ServiceImpl"> 2 //@Component("userService") 3 @Service("userService") 4 public class UserServiceImpl implements UserService{ 5 //<property name="userDao" ref="userDao"></property> 6 /* @Autowired //按照数据类型从Spring容器中进行匹配 7 @Qualifier("userDao") //按照id值从容器中进行匹配的 但是此处 @Qualifier要结合@Autowired一起使用 8 */ 9 @Resource(name = "userDao") // @Resource相当于@Qualifier+@Autowired 10 private UserDao userDao; 11 12 public void save() { 13 域名(); 14 } 15 }
然后,来到web层进行测试,运行结果如下:
可以发现报错了,说没有UserService这个bean定义的异常,那么为什么没有呢,那么刚刚把xml中的配置转成注解的时候,用的是Component标签,注入用到的是Autowired和Qualifier,但是现在有个问题,我们把这个注解配到这,还得告诉Spring,它要去哪里拿,去找那个注解,然后读取注解再帮忙创建我们需要的对象,所以要怎么告诉,就得配置组件扫描。
注意:
使用注解开发时,需要在域名中配置组件扫描,作用是指定那个包及其包下的Bean需要进行扫描以便于识别使用注解配置的类、字段和方法。
<!-- 配置组件扫描--> <context:component-scan base-package="域名t"/>
base-package:属性就是基本包,你给定一个基本包,Spring就会扫描这个包以及它的子包后边的所有的bean都会被扫描,扫到对应的注解,Spring就会帮你去解析,就能完成bean的创建和注入工作
配置完组件扫描,再去测试,运行结果:
使用@Value进行字符串注入
1 @Repository("userDao") 2 public class UserDaoImpl implements UserDao{ 3 4 @Value("aabcccddddd") //普通数据 5 private String str; 6 @Value("${域名er}") //注入外部数据 7 private String driver; 8 9 public void save() { 10 域名tln(str); 11 域名tln(driver); 12 域名tln("Save Running...."); 13 } 14 }
使用@Scope 标注Bean的范围
@Service("userService") @Scope("prototype") public class UserServiceImpl implements UserService{ ....... }
使用@PostConstruct 标注初始化方法,使用@PreDestroy 标注销毁方法
1 @PostConstruct 2 public void init() { 3 域名tln("Service对象的初始化方法"); 4 } 5 @PreDestroy 6 public void destory(){ 7 域名tln("Service对象的销毁方法"); 8 } 9 10 public class UserController { 11 public static void main(String[] args) { 12 ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("域名"); 13 UserService userService = 域名ean(域名s); 14 域名(); 15 域名e(); 16 } 17 }
2.2 Spring新注解
使用以上注解不能全部替代xml配置文件,还需要使用注解替代的配置如下:
-
非自定义的Bean的配置:<Bean>
-
加载properties文件的配置:<context:property-placeholder>
-
组件扫描配置:<context:component-scan>
-
引入其他文件:<import>
注解 | 说明 |
---|---|
@Configuration | 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 |
@ComponentScan |
用于指定Spring在初始化容器时要扫描的包 作用和在Spring的xml配置文件中的 <context:component-scan base-packsge="域名t"/>一样 |
@Bean | 使用在方法上,标注将该方法的返回值存储到Spring容器中 |
@propertySource | 用于加载 .properties 文件中的配置 |
@import | 用于导入其他配置类 |
1 //context:property-placeholder location="classpath:域名erties"/> 2 @PropertySource("classpath:域名erties") 3 public class DataSourceConfiguration { 4 5 @Value("${域名er}") 6 private String driver; 7 @Value("${域名}") 8 private String url; 9 @Value("${域名name}") 10 private String username; 11 @Value("${域名word}") 12 private String password; 13 14 @Bean("dataSource") //Spring会将当前方法的返回值以指定存储到Spring容器中 15 public DataSource getDatasource() throws PropertyVetoException { 16 ComboPooledDataSource dataSource = new ComboPooledDataSource(); 17 域名riverClass(driver); 18 域名dbcUrl(url); 19 域名ser(username); 20 域名assword(password); 21 return dataSource; 22 }
1 //标志该类是Spring的核心配置类 2 @Configuration 3 //<context:component-scan base-package="域名t"/> 4 @ComponentScan("域名t") 5 //<import resource=""/> 6 @Import({域名s}) 7 public class SpringConfiguration { 8 9 10 }
加载核心配置进行测试
1 public class UserController { 2 public static void main(String[] args) { 3 ApplicationContext app = new AnnotationConfigApplicationContext(域名s); 4 UserService userService = 域名ean(域名s); 5 域名(); 6 } 7 }
3. Spring整合Junit
3.1 原始junit测试Spring的问题
在测试类中的每个方法都要有如下两行代码,其作用是获取容器。如果没有则会提示空指针异常
ApplicationContext app = new ClassPathXmlApplicationContext("域名"); DataSource dataSource = 域名ean(域名s);
3.2 解决思路
-
使SpringJunit负责创建Spring容器,需要告诉配置文件的名称
-
将需要进行测试Bean 直接在测试类中进行注入
3.3 Spring集成Junit步骤
-
导入Spring集成Junit的坐标
-
使用@Runwith注解替换原来的运行期
-
使用@ContextConfiguration指定配置文件或配置类
-
使用@Autowired注入需要测试的对象
-
创建测试方法进行测试
3.4 Spring集成Junit代码实现
1、导入Spring集成Junit的坐标
<dependency> <groupId>域名ngframework</groupId> <artifactId>spring-context</artifactId> <version>域名</version> <scope>test</scope> </dependency> <dependency> <groupId>域名ngframework</groupId> <artifactId>spring-test</artifactId> <version>域名</version> </dependency>
2、使用@Runwith注解替换原来的运行期
@RunWith(域名s) public class SpringJunitTest { }
3、使用@ContextConfiguration指定配置文件或配置类
1 @RunWith(域名s) 2 //加载Spring核心配置类 3 //@ContextConfiguration(classes = {域名s}) 4 //加载Spring核心配置文件 5 @ContextConfiguration("classpath:域名") 6 public class SpringJunitTest { 7 8 }
4、使用@Autowired注入需要测试的对象
1 @RunWith(域名s) 2 //加载Spring核心配置类 3 //@ContextConfiguration(classes = {域名s}) 4 //加载Spring核心配置文件 5 @ContextConfiguration("classpath:域名") 6 public class SpringJunitTest { 7 8 @Autowired 9 private UserService userService; 10 11 }
5、 创建测试方法进行测试
1 @RunWith(域名s) 2 //加载Spring核心配置类 3 //@ContextConfiguration(classes = {域名s}) 4 //加载Spring核心配置文件 5 @ContextConfiguration("classpath:域名") 6 public class SpringJunitTest { 7 8 @Autowired 9 private UserService userService; 10 11 @Test 12 public void UserServiceTest(){ 13 域名(); 14 } 15 }
运行结果: