Spring
一、配置文件
1.1 Bean基本配置
<bean id="userDao" class="com.tys.dao.UserDaoImpl"></bean>
1. 用于配置对象交由Spring来创建
2. 默认情况下它调用的是类中的无参构造函数,如果没有无参构造则创建不成功
3. id:Bean实例在Spring容器中的唯一标识
4. class:Bean的全限定名
1.2 Bean范围配置
取值范围 | 说明 |
---|---|
singleton | 默认值,单一对象 |
prototype | 多个对象,即每次getBean都是一个新的对象 |
request | Spring创建一个Bean的对象同时将对象存入到request域中 |
session | Spring创建一个Bean的对象同时将对象存入到session域中 |
global session | 应用在Portlet环境,如果没有Portlet环境那么相当于session |
//单一对象:scope="singleton"
<bean id="userDao" class="com.tys.dao.UserDaoImpl" scope="singleton"></bean>
(1)Bean的实例化个数:1个
(2)Bean的实例化时机:当加载Spring配置文件时,实例化Bean对象
(3)Bean的生命周期:
对象创建:当创建Spring容器时,对象就被创建了。
对象运行:只要容器在,对象一直在。
对象销毁:当销毁容器时,对象就被销毁了。
=====================================================================================
//多个对象:scope="prototype"
<bean id="userDao" class="com.tys.dao.UserDaoImpl" scope="prototype"></bean>
(1)Bean的实例化个数:多个
(2)Bean的实例化时机:当调用getBean()方法时,实例化Bean对象
(3)Bean的生命周期:
对象创建:当getBean()对象时,创建新的对象实例
对象运行:只要对象在使用中,对象就一直存在
对象销毁:当对象长时间不用时,被gc垃圾回收器回收了
1.3 Bean生命周期配置
//init-method:指定类中的初始化方法,destroy-method:指定类中的销毁方法
//在UserDaoImpl里,写public void init(){System.out.println("初始化方法");}
//在UserDaoImpl里,写public void destroy(){System.out.println("销毁方法");}
<bean id="userDao" class="com.tys.dao.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
//Spring执行顺序:先执行创建bean对象,再执行初始化方法,再执行正常的功能代码,最后执行销毁方法
1.4 Bean实例化的三种方式
无参构造方法实例化,这个最常用,看快速入门就是无参构造方法
<bean id="userDao" class="com.tys.dao.UserDaoImpl"></bean>
工厂静态方法实例化
package com.tys.factory;
import com.tys.dao.*;
public class StaticFactory {
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
===================================================================================
//前面class还是在找无参构造,主要加上factory-method="方法名"
<bean id="userDao" class="com.tys.factory.StaticFactory" factory-method="getUserDao"></bean>
工厂实例方法实例化
package com.tys.factory;
import com.tys.dao.*;
public class StaticFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
===================================================================================
//代码两个都一样,只是上一个有static
//这个没有static就需要先创建工厂对象,再加上factory-method="方法名"
<bean id="factory" class="com.tys.factory.StaticFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
1.5 Bean依赖注入两种方式
set方法
package com.tys.service;
import com.tys.dao.UserDao;
public class UserServiceImpl implements UserService{
private UserDao userDao; //先创建dao层对象,再通过set方法,传递给service层
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
===================================================================================
<bean id="userDao" class="com.tys.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.tys.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
//property的name是set方法名,即setUserDao的首字母小写,ref指向第一行创建的bean对象
有参构造方法注入
package com.tys.service;
import com.tys.dao.UserDao;
public class UserServiceImpl implements UserService{
private UserDao userDao; //使用有参构造,这儿必须先定义一个无参构造
public UserServiceImpl() {
}
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
===================================================================================
<bean id="userDao" class="com.tys.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.tys.service.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
//constructor-arg的name是有参构造的形参列表创建的userDao,ref指向第一行创建的bean对象
1.6 Bean依赖注入数据类型
注入数据的三种数据类型:引用类型数据,普通类型数据,集合类型数据
注入引用类型数据:前面的userdao注入到userservice都是注入引用类型数据
注入普通类型数据:
package com.tys.dao;
public class UserDaoImpl implements UserDao {
private String username;
private int age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void save() {
System.out.println(username+"==="+age);
System.out.println("save running...");
}
}
=====================================================================================
<bean id="userDao" class="com.tys.dao.UserDaoImpl">
<property name="username" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
注入集合类型数据:
package com.tys.dao;
import java.util.*;
public class UserDaoImpl implements UserDao {
private List<String> strList;
private Map<String,User> userMap; //这儿的User是引用对象,也就是下面的User类
private Properties properties;
public List<String> getStrList() {
return strList;
}
public void setStrList(List<String> strList) {
this.strList = strList;
}
public Map<String, User> getUserMap() {
return userMap;
}
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public void save() {
System.out.println(strList);
System.out.println(userMap);
System.out.println(properties);
System.out.println("save running...");
}
}
=======================================================================================
//User类
package com.tys.dao;
public class User {
private String name;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
=======================================================================================
<bean id="userDao" class="com.tys.dao.UserDaoImpl">
<property name="strList">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="userMap">
<map>
<entry key="u1" value-ref="user1"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="p1">ppp</prop>
</props>
</property>
</bean>
//这儿是依赖注入User对象
<bean id="user1" class="com.tys.dao.User">
<property name="name" value="Tom"></property>
<property name="address" value="Shanghai"></property>
</bean>
1.7 引入其他配置文件
- 实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大
- 分模块开发,比如按照业务模块进行拆解,你负责用户模块,他负责产品模块
- 所以可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载
<import resource="applicationContext-user.xml" />
<import resource="applicationContext-conductor.xml" />
1.8 ApplicationContext实现类
举例:
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService=(UserService) app.getBean("userService");
userService.save();
ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件,推荐使用这个
FileSystemXmlApplicationContext
它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建Spring容器,它用来读取注解
app.getBean("id")
如果容器中某一类型的bean,存在多个,就要id方式获取
app.getBean(UserService.class) UserService可以换成其他的类名
如果容器中某一类型的bean,存在1个,就可以用类方式获取
二、配置C3P0数据源
2.1 创建web项目
1.左上文件==新建==项目==左侧选择空项目==输入项目名SpringJDBC==点击创建
2.左上文件==新建==模块==左侧选择Maven Archetype==输入:Test01==选择maven-archetype-webapp
3.点开高级设置==鼠标往下拉==组ID输入com.tys和版本号1.0==点击创建
4.对着src==右键新建==目录==全选==回车
2.2 加入依赖
//pom.xml,点右侧maven,刷新
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
2.3 jdbc配置文件
//选中src/main/resources==右键新建==文件==jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/companydb
jdbc.username=root
jdbc.password=123456
2.4 xml配置文件
//对着src/main/resources==右键新建==XML配置文件==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"
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">
<!--加载外部的properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>
2.5 创建对象
//对着src/main/java==右键新建==软件包==com.tys.test
//对着com.tys.test==右键新建==Java类==DataSourceTest
package com.tys.test;
import org.springframework.context.*;
import org.springframework.context.support.*;
import javax.sql.*;
import java.sql.*;
public class DataSourceTest {
public static void main(String[] args) throws Exception {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource=(DataSource)app.getBean("dataSource");
Connection conn= dataSource.getConnection();
System.out.println(conn);
conn.close();
}
}
//对着空白处==右键运行==控制台输出:c3p0的地址=代表成功
三、注解开发
3.1 Spring注解
注解(实例化Bean) | 说明 |
---|---|
@Component(“userDao”) | 在类上实例化Bean |
@Controller | 在web层上实例化Bean,与@Component功能一样,语义化更强 |
@Service(“userService”) | 在service层上实例化Bean,与@Component功能一样,语义化更强 |
@Repository(“userDao”) | 在dao层上实例化Bean,与@Component功能一样,语义化更强 |
注解(依赖注入) | 说明 |
---|---|
@Autowired | 使用在字段上,按照类型进行依赖注入 |
@Qualifier(“userDao”) | 一般结合@Autowired,按照名称进行依赖注入 |
@Resource(name=“userDao”) | 相当于@Autowired+@Qualifier,按照名称进行依赖注入 |
注解(原始注解) | 说明 |
---|---|
@Value(“zhangsan”)/@Value(“${jdbc.driver}”) | 注入普通属性/获取键值对 |
@Scope(“prototype”) | 标注Bean的作用范围 |
@PostConstruct | 标注该方法是Bean的初始化方法 |
@PreDestroy | 标注该方法是Bean的销毁方法 |
注解(新注解) | 说明 |
---|---|
@Configuration | 用于指定当前类是一个Spring配置类,代替Spring的xml配置文件 |
@Bean(“dataSource”) | 自定义bean,代替C3P0的xml文件 |
@PropertySource(“classpath:jdbc.properties”) | 用于加载properties文件中的配置 |
@Import({DataSourceConfig.class,XXX.class}) | 用于导入其他配置类,配置类都是@Configuration,也就是class文件而非xml,多个配置类数组形式逗号隔开 |
3.2 组件扫描
使用注解进行开发,需要在applicationContext.xml 中配置组件扫描,也可用注解代替xml进行组件扫描
作用是指定哪个包及其子包下的Bean需要进行扫描以便Spring扫描到之后进行创建对象
<!--配置组件扫描-->
<context:component-scan base-package="com.tys"></context:component-scan>>
注解(新注解) | 说明 |
---|---|
@ComponentScan(“com.tys”) | 用于指定Spring在初始化容器时要扫描的包 |
3.3 AOP开发
(1)pom.xml
//pom.xml,点右侧maven,刷新
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
(2)创建目标接口和目标类
//对着src/main/java==右键新建==软件包==com.tys.aop
//对着com.tys.aop==右键新建==Java类==TargetInterface
public interface TargetInterface {
public void save();
}
//对着com.tys.aop==右键新建==Java类==Target
public class Target implements TargetInterface{
@Override
public void save() {
System.out.println("save running...");
}
}
(3)创建切面类
//对着com.tys.aop==右键新建==Java类==MyAspect
public class MyAspect {
public void before(){
System.out.println("前置增强....");
}
}
(4)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"
xmlns:aop="http://www.springframework.org/schema/aop"
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="target" class="com.tys.aop.Target"></bean>
<!-- 切面对象-->
<bean id="myAspect" class=