Spring注解开发
阅读 (824780)1、注解开发-上
1.1、创建一个新的项目
通过maven创建一个新的项目spring004
1.2、导入jar包
在原有的jar包的基础上加入spring-aop的jar包
<?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.tyshcool</groupId>
<artifactId>spring004</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.3</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
</dependencies>
</project>
1.3、编写业务层与持久层
IManagerService.java
public interface IManagerService {
public void findAll();
}
ManagerServiceImpl.java
import com.tyschool.spring004.manager.service.IManagerService;
public class ManagerServiceImpl implements IManagerService {
public void findAll() {
}
}
IManagerDao.java
public interface IManagerDao {
public void findAll();
}
ManagerDaoImpl.java
import com.tyschool.spring004.manager.dao.IManagerDao;
public class ManagerDaoImpl implements IManagerDao {
public void findAll() {
System.out.println("执行到了这里");
}
}
1.4、创建applicationContext文件
1.4.1、加入context约束
xmlns:context="http://www.springframework.org/schema/context" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
注解整合时,需要多导入一个 context 名称约束,可以通过context去导入包。
1.4.2、增加扫描包
<!--spring 创建对象时要扫描的包 -->
<context:component-scan base-package="com.tyschool.spring004.manager"></context:component-scan>
2、注解开发-下
2.1、配置对象
@Component(“beanName”)
相当于在 xml 中配置一个 bean。
2.1.1、修改业务层实现类
import com.tyschool.spring004.manager.dao.IManagerDao;
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.stereotype.Component;
@Component("managerServiceImpl")
public class ManagerServiceImpl implements IManagerService {
@Autowired
private IManagerDao managerDaoImpl;
public void findAll() {
managerDaoImpl.findAll();
}
}
2.1.2、修改持久层的实现类
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.stereotype.Component;
@Component("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {
public void findAll() {
System.out.println("执行到了这里");
}
}
2.2、测试
2.2.1、导入jar包
spring test和junit
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.2.RELEASE</version>
<scope>test</scope>
</dependency>
2.2.2、编写测试类
@Runwith 注解替换原来的运行期
@ContextConfifiguration 指定配置文件或配置类
@Autowired 注入需要测试的对象
STest.java
import com.tyschool.spring004.manager.service.IManagerService;
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;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"classpath:applicationContext.xml"})
public class STest {
@Autowired
private IManagerService managerServiceImpl;
@Test
public void findAll(){
managerServiceImpl.findAll();
}
}
3、spring常用注解(对象创建)
3.1、@Component
作用:
声明一个Bean
属性:
value:默认 bean 的 id 是当前类的类名。首字母小写。可以通过value指定
@Component("managerDaoImpl")
3.2、@Controller、@Service、@Repository
@Controller 在展现层使用,控制器的声明(C)
@Service 在业务逻辑层使用(service层)
@Repository 在数据访问层使用(dao层)
3.2.1、修改业务层
import com.tyschool.spring004.manager.dao.IManagerDao;
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
//@Component("managerServiceImpl")
@Service("managerServiceImpl")
public class ManagerServiceImpl implements IManagerService {
@Autowired
private IManagerDao managerDaoImpl;
public void findAll() {
managerDaoImpl.findAll();
}
}
3.2.2、修改持久层
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
//@Component("managerDaoImpl")
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {
public void findAll() {
System.out.println("执行到了这里");
}
}
测试
4、spring常用注解(数据注入)-上
4.1、@Autowired
作用:
注解注入各种类型,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。
@Autowired
private IManagerDao managerDaoImpl;
如果这里不用@Autowired会报空指针异常。
4.2、@Qualifier
作用:
表明了哪个实现类才是我们所需要的,与@Autowired()一起使用
创建另一个service
ManagerServiceImpl1.java
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.stereotype.Service;
@Service("managerServiceImpl1")
public class ManagerServiceImpl1 implements IManagerService {
public void findAll() {
System.out.println("这是另一个service");
}
}
修改测试类
public class STest {
@Autowired()
@Qualifier("managerServiceImpl")
private IManagerService ims ;
@Test
public void findAll(){
ims.findAll();
}
}
4.3、@Resource
作用:
按照 Bean 的 id 注入
修改测试类:
public class STest {
// @Autowired()
// @Qualifier("managerServiceImpl")
@Resource(name="managerServiceImpl1")
private IManagerService ims ;
@Test
public void findAll(){
ims.findAll();
}
}
注意:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
与@Autowired区别:
@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
@Resource(这个注解属于JavaEE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
5、spring常用注解(数据注入)-下
5.1、@Value
作用:
将我们配置文件的属性读出来,有@Value(“”)、@Value("${}")和@Value("#{}")三种方式
@Value(“”) 基本数据的填充
@Value("${}") 基于配置文件
@Value("#{}") 基于SpEl表达式
5.1.1、@Value(“”)
修改ManagerDaoImpl.java文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {
@Value("路径")
private String path;
public void findAll() {
System.out.println("执行到了这里");
System.out.println(path);
}
}
测试
文件与URL地址注入
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {
@Value("路径")
private String path;
@Value("classpath:1.txt")
private Resource resource;//用来存储资源
@Value("http://www.baidu.com")
private Resource resource1;
public void findAll() {
System.out.println("执行到了这里");
System.out.println(path);
System.out.println(resource);
System.out.println(resource1);
}
}
注意:
boolean exists(); 用来判断资源是否存在
boolean isOpen() ; 用来判断资源是否打开
URL getURL() ;如果底层资源可以表示成 URL ,那么该方法可以返回一个 URL对象。
File getFile() ;如果底层资源对应着一个文件 ,那么该方法可以返回一个 File对象。
String getFilename(); 返回底层资源对应的文件名。
InputStream getInputStream() ;返回底层资源对应输入流。
5.1.2、@Value("#{}")
修改ManagerDaoImpl.java文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import java.io.IOException;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {
@Value("#{'abcdefg'}")
private String str;
@Value("#{systemProperties['os.name']}")
private String systemname; // 注入操作系统属性
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double number; //注入表达式结果
@Value("#{manager.uname}")
private String uname; // 注入其他Bean属性:注入manager对象的属性uname,类具体定义见下面
public void findAll() {
System.out.println("执行到了这里");
System.out.println(str);
System.out.println(systemname);
System.out.println(number);
System.out.println(uname);
}
}
Manager.java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class Manager {
private int mid;
@Value("你好")
private String uname;
private String pword;
private Date zcsj;
public int getMid() {
return mid;
}
public void setMid(int mid) {
this.mid = mid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPword() {
return pword;
}
public void setPword(String pword) {
this.pword = pword;
}
public Date getZcsj() {
return zcsj;
}
public void setZcsj(Date zcsj) {
this.zcsj = zcsj;
}
@Override
public String toString() {
return "Manager{" +
"mid=" + mid +
", uname='" + uname + '\'' +
", pword='" + pword + '\'' +
", zcsj=" + zcsj +
'}';
}
}
5.1.3、@Value("${}")
创建data.properties
s1=this is there
修改applicationContext.xml文件
<context:property-placeholder location="classpath:data.properties" />
修改ManagerDaoImpl.java文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import java.io.IOException;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {
@Value("${s1}")
private String data;
public void findAll() {
System.out.println("执行到了这里");
System.out.println(data);
}
}
6、spring常用注解(作用范围)
6.1、@Scope
作用:
@Scope注解是SpringIOC容器中的一个作用域,在 Spring IOC 容器中具有以下几种作用域:基本作用域singleton(单例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定义作用域
6.1.1、单例
singleton单例模式 – 全局有且仅有一个实例
修改STest.java文件
import com.tyschool.spring004.manager.service.IManagerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"classpath:applicationContext.xml"})
public class STest {
@Resource(name="managerServiceImpl")
private IManagerService ims ;
@Resource(name="managerServiceImpl")
private IManagerService ims1 ;
@Test
public void findAll(){
System.out.println(ims);
System.out.println(ims1);
//ims.findAll();
}
}
6.1.2、多例
prototype原型模式 – 每次获取Bean的时候会有一个新的实例
修改ManagerServiceImpl.java文件
import com.tyschool.spring004.manager.dao.IManagerDao;
import com.tyschool.spring004.manager.service.IManagerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Scope(value = "prototype")
@Service("managerServiceImpl")
public class ManagerServiceImpl implements IManagerService {
@Autowired
private IManagerDao managerDaoImpl;
@Value("这是一个S")
private String s;
public void findAll() {
managerDaoImpl.findAll();
}
}
测试
6.1.3、其他
request – request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
session – session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
global session – global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet(Portlet是基于Java的Web组件,由Portlet容器管理,并由容器处理请求,生产动态内容。如:单点登录)的web应用中才有意义
7、spring常用注解(bean生命周期)
7.1、@PostConstruct
作用:
实现初始化,相当于init-method属性
7.2、@PreDestroy
作用:
实现销毁,相当于 destroy-method属性
7.3、测试
编写测试类STest1.java文件
import com.tyschool.spring004.manager.service.IManagerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value={"classpath:applicationContext.xml"})
public class STest1 {
@Autowired
@Qualifier("managerServiceImpl")
private IManagerService ims;
public STest1(){
System.out.println("ims:"+ims);
}
@PostConstruct
public void init(){
System.out.println("init:"+ims);
}
@PreDestroy
public void destroy(){
System.out.println("destroy:"+ims);
}
@Test
public void test(){
//new STest1();
System.out.println("test:"+ims);
}
}
8、纯注解开发-上
8.1、配置问题
前面我们虽然使用了注解,但是我们还是使用了xml文件,如果解决xml文件问题?
8.2、 @Configuration
作用:
用于指定配置类,当我们创建容器时,从指定的配置类中加载。
创建配置类
SpringApplicationContext.java
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringApplicationContext {
}
8.3、@ComponentScan
作用:
用于指定初始化容器时,要扫描的包。
修改配置类
SpringApplicationContext.java
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.tyschool.spring004")
public class SpringApplicationContext {
}
删除配置文件applicationContext.xml
8.4、@Bean
作用:
创建Bean对象,只能用在方法上。
创建连接池与DBUtils配置类
DbUtilsC3P0.java
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
public class DbUtilsC3P0 {
//配置数据源
@Bean(name="dataSource")
public DataSource createDateSource(){
ComboPooledDataSource cds=new ComboPooledDataSource();
try {
cds.setDriverClass("com.mysql.cj.jdbc.Driver");
cds.setJdbcUrl("jdbc:mysql://192.168.1.123:3306/spring?serverTimezone=UTC");
cds.setUser("root");
cds.setPassword("Root12345");
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return cds;
}
@Bean(name="queryRunner")
public QueryRunner createQueryRunner(DataSource dataSource){
return new QueryRunner(dataSource);
}
}
9、纯注解开发-下
9.1、@PropertySource
作用:
加载配置文件(.properties),在书写路径时要加classpath
9.1.1、配置文件优化一
修改DbUtilsC3P0.java文件
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
public class DbUtilsC3P0 {
@Value("com.mysql.cj.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://192.168.1.123:3306/spring?serverTimezone=UTC")
private String url;
@Value("root")
private String username;
@Value("Root12345")
private String password;
//配置数据源
@Bean(name="dataSource")
public DataSource createDateSource(){
ComboPooledDataSource cds=new ComboPooledDataSource();
try {
cds.setDriverClass(driver);
cds.setJdbcUrl(url);
cds.setUser(username);
cds.setPassword(password);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return cds;
}
@Bean(name="queryRunner")
public QueryRunner createQueryRunner(DataSource dataSource){
return new QueryRunner(dataSource);
}
}
9.1.2、配置文件优化二
创建db.properties文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.1.123:3306/spring?serverTimezone=UTC
jdbc.username=root
jdbc.password=Root12345
修改DbUtilsC3P0.java文件
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
@PropertySource(value={"classpath:db.properties"},ignoreResourceNotFound = false)
public class DbUtilsC3P0 {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//配置数据源
@Bean(name="dataSource")
public DataSource createDateSource(){
ComboPooledDataSource cds=new ComboPooledDataSource();
try {
cds.setDriverClass(driver);
cds.setJdbcUrl(url);
cds.setUser(username);
cds.setPassword(password);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return cds;
}
@Bean(name="queryRunner")
public QueryRunner createQueryRunner(DataSource dataSource){
return new QueryRunner(dataSource);
}
}
注意:
ignoreResourceNotFound 表示没有找到文件是否会报错,默认为false,就是会报错,一般开发情况应该使用默认值,设置为true相当于生吞异常,增加排查问题的复杂性.
9.2、@Import
作用:
导入配置类
修改DbUtilsC3P0.java文件
@Configuration
@ComponentScan("com.tyschool.spring004")
@Import({DbUtilsC3P0.class})
public class SpringApplicationContext {
}
9.3、测试
修改ManagerDaoImpl.java文件
import com.tyschool.spring004.javabean.Manager;
import com.tyschool.spring004.manager.dao.IManagerDao;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
@Repository("managerDaoImpl")
public class ManagerDaoImpl implements IManagerDao {
@Autowired
private QueryRunner queryRunner;
public void findAll() {
try {
List<Manager> list=queryRunner.query("select * from manager", new BeanListHandler<Manager>(Manager.class));
for(Manager m:list){
System.out.println(m);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
创建测试类STest2.java文件
import com.tyschool.spring004.manager.service.IManagerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = com.tyschool.spring004.utils.SpringApplicationContext.class)
public class STest2 {
@Resource(name="managerServiceImpl")
private IManagerService ims ;
@Test
public void findAll(){
ims.findAll();
}
}