bean注解 别人的方法使用方法配
依赖 properties配置版本 <spring.version > 5.1.8.RELEASE</spring.version >
spring.xml 配置在resources文件下
<?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 >
要new对象实例 dao层 package day1.dao;import java.util.List;public interface UserDao { public List getList () ; }
impl层 package day1.dao.impl;import day1.dao.UserDao;import java.util.List;public class UserDaoimpl implements UserDao { @Override public List getList () { System.out.println("到数据库查询!" ); return null ; } }
spring.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 id ="User" class ="day1.dao.impl.UserDaoimpl" /> </beans >
测试 package com.test;import day1.dao.UserDao;import day1.service.UserService;import org.junit.Test;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import java.util.Date;import java.util.List;public class UserDaoTest { @Test public void userimpl () { ClassPathXmlApplicationContext contxt=new ClassPathXmlApplicationContext ("spring.xml" ); System.out.println("容器开启!" ); UserDao us= (UserDao) contxt.getBean("User" ); us.getList(); contxt.close(); } }
类返回对象 dao层 package day1.dao;import java.util.ArrayList;import java.util.Date;import java.util.List;public class WomenFactory { public Date GetWomen () { return new Date (); } }
spring.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 id ="Women" class ="day1.dao.WomenFactory" /> <bean id ="getmo" factory-bean ="Women" factory-method ="GetWomen" /> </beans >
测试 package com.test;import day1.dao.UserDao;import day1.service.UserService;import org.junit.Test;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import java.util.Date;import java.util.List;public class UserDaoTest { @Test public void userimpl () { ClassPathXmlApplicationContext contxt=new ClassPathXmlApplicationContext ("spring.xml" ); System.out.println("容器开启!" ); Date da= (Date) contxt.getBean("getmo" ); System.out.println(da); contxt.close(); } }
静态方法返回对象 dao层 package day1.dao;import java.util.ArrayList;import java.util.Date;import java.util.List;public class WomenFactory { public static List GetPileWomen () { List lis=new ArrayList (); lis.add("Women1" ); lis.add("Women2" ); lis.add("Women3" ); lis.add("Women4" ); return lis; } }
spring.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 id ="getwomlis" class ="day1.dao.WomenFactory" factory-method ="GetPileWomen" /> </beans >
测试 package com.test;import day1.dao.UserDao;import day1.service.UserService;import org.junit.Test;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import java.util.Date;import java.util.List;public class UserDaoTest { @Test public void userimpl () { ClassPathXmlApplicationContext contxt=new ClassPathXmlApplicationContext ("spring.xml" ); System.out.println("容器开启!" ); List lis= (List) contxt.getBean("getwomlis" ); System.out.println(lis); contxt.close(); } }
依赖注入 控制反转 控制反转(IOC) 依赖注入(Dependency Injection)
依赖顺序:UserServiceImpl–>UserServiceDao UserDaoimpl–>UserDao
简单说就是:UserServiceImpl–>UserDao 主要是这两个依赖 而UserDao是接口多个类可以实现这个接口
dao层 package day1.dao;import java.util.List;public interface UserDao { public List getList () ; }
impl层 package day1.dao.impl;import day1.dao.UserDao;import java.util.List;public class UserDaoimpl implements UserDao { @Override public List getList () { System.out.println("到数据库查询!" ); return null ; } }
Service package day1.service;import java.util.List;public interface UserService { public void getlis () ; }
Serviceimpl package day1.service.impl;import day1.dao.UserDao;import day1.service.UserService;import java.util.List;public class UserServiceImpl implements UserService { UserDao us; public void setUs (UserDao us) { this .us = us; } @Override public void getlis () { System.out.println("Usr dao层" ); us.getList(); } }
spring.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 id ="Useryl" class ="day1.dao.impl.UserDaoimpl" /> <bean id ="Uservic" class ="day1.service.impl.UserServiceImpl" > <property name ="us" ref ="Useryl" /> </bean > </beans >
测试 package com.test;import day1.dao.UserDao;import day1.service.UserService;import org.junit.Test;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import java.util.Date;import java.util.List;public class UserDaoTest { @Test public void userimpl () { ClassPathXmlApplicationContext contxt=new ClassPathXmlApplicationContext ("spring.xml" ); System.out.println("容器开启!" ); UserService ussrvic= (UserService) contxt.getBean("Uservic" ); ussrvic.getlis(); contxt.close(); } }
配置解释 注:(和上面四大块类似)
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xlns: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 ="getuslis" class ="com.dao.impl.UserDaoimpl" /> <bean id ="moen" class ="com.dao.Women" /> <bean id ="getmdate" factory-bean ="moen" factory-method ="getda" /> <bean id ="stafound" class ="com.dao.Women" factory-method ="lis" /> <bean id ="usdao" class ="com.dao.impl.UserDaoimpl" /> <bean id ="serv" class ="com.service.impl.UserServiceDaoimpl" > <property name ="usd" ref ="usdao" /> </bean > </beans >
三种创建工厂方法 1 、ClassPathXmlApplicationContext con=new ClassPathXmlApplicationContext ("配置文件名" ) 2 、Resource res = new ClassPathResource ("配置文件名" );3 、 BeanFactory factory = new XmlBeanFactory (res);4 、自己创建工厂 用方法去
spring放对象的方法 3种 1、 <bean id ="getuslis" class ="com.dao.impl.UserDaoimpl" /> 2、 <bean id ="moen" class ="com.dao.Women" /> <bean id ="getmdate" factory-bean ="moen" factory-method ="getda" /> 3、 <bean id ="stafound" class ="com.dao.Women" factory-method ="lis" />
自己创建工厂 配置 文件名: bean.properties
userdao =day1.dao.impl.UserDaoimpl userservice =day1.service.impl.UserServiceDaoimpl
实现类 package day1.utils;import org.springframework.context.annotation.Bean;import java.io.IOException;import java.io.InputStream;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import java.util.Properties;public class MyFactory { static Properties prop; private static Map<String, Object> beans=new HashMap <String, Object>(); static { InputStream inpt=MyFactory.class.getClassLoader().getResourceAsStream("bean.properties" ); prop =new Properties (); try { prop.load(inpt); Enumeration em=prop.keys(); while (em.hasMoreElements()){ String key= (String) em.nextElement(); String popcontxt=prop.getProperty(key); Object obj=Class.forName(popcontxt).newInstance(); beans.put(key,obj); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static Object getbean (String key) { return beans.get(key); } }
测试 import day1.service.UserviceDao;import day1.utils.MyFactory;import org.junit.Test;public class TestMyFactory { @Test public void testmyfa () { UserviceDao obj=(UserviceDao)MyFactory.getbean("userservice" ); System.out.println(obj); } }
依赖注入 普通注入 实体注入类MyInfo
package day2;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.Set;public class MyInfo { String name; String [] myst; List<String> lis; Set<String> sel; Map<String,String> maps; public void setName (String name) { this .name = name; } public void setMyst (String[] myst) { this .myst = myst; } public void setLis (List<String> lis) { this .lis = lis; } public void setSel (Set<String> sel) { this .sel = sel; } public void setMaps (Map<String, String> maps) { this .maps = maps; } public void show () { System.out.println(name); System.out.println(Arrays.toString(myst)); System.out.println(lis); System.out.println(sel); System.out.println(maps); } }
配置
<bean id ="temo" class ="day2.MyInfo" > <property name ="name" value ="张三" > </property > <property name ="myst" > <list > <value > 提莫</value > <value > 妲己</value > <value > 后羿</value > </list > </property > <property name ="lis" > <list > <value > 提莫2</value > <value > 妲己2</value > <value > 后羿2</value > </list > </property > <property name ="sel" > <set > <value > 北京</value > <value > 上海</value > <value > 南京</value > </set > </property > <property name ="maps" > <map > <entry key ="java" value ="Java2" /> <entry key ="java2" value ="Java2" /> <entry key ="java3" value ="Java2" /> </map > </property > </bean >
测试
import day2.MyInfo;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestDay2 { @Test public void testday () { ClassPathXmlApplicationContext con=new ClassPathXmlApplicationContext ("spring-day2.xml" ); MyInfo my= (MyInfo) con.getBean("temo" ); my.show(); } }
实体注入 实体类
package day2;public class Heros { public int price; public String name; public int getPrice () { return price; } public void setPrice (int price) { this .price = price; } public String getName () { return name; } public void setName (String name) { this .name = name; } public Heros () { } public Heros (int price, String name) { this .price = price; this .name = name; } @Override public String toString () { return "Heros{" + "price=" + price + ", name='" + name + '\'' + '}' ; } }
实体注入类MyInfo
package day2;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.Set;public class MyInfo { String name; String [] myst; List<Heros> lis; Set<Heros> sel; Map<String,Heros> maps; public void setName (String name) { this .name = name; } public void setMyst (String[] myst) { this .myst = myst; } public void setLis (List<Heros> lis) { this .lis = lis; } public void setSel (Set<Heros> sel) { this .sel = sel; } public void setMaps (Map<String, Heros> maps) { this .maps = maps; } public void show () { System.out.println(name); System.out.println(Arrays.toString(myst)); System.out.println(lis); System.out.println(sel); System.out.println(maps); } }
配置
<bean id ="js" class ="day2.Heros" > <property name ="price" value ="100" > </property > <property name ="name" value ="后羿" > </property > </bean > <bean id ="js2" class ="day2.Heros" > <property name ="price" value ="500" > </property > <property name ="name" value ="数据库" > </property > </bean > <bean id ="temo" class ="day2.MyInfo" > <property name ="name" value ="张三" > </property > <property name ="myst" > <list > <value > 提莫</value > <value > 妲己</value > <value > 后羿</value > </list > </property > <property name ="lis" > <list > <ref bean ="js2" > </ref > <ref bean ="js" > </ref > </list > </property > <property name ="maps" > <map > <entry key ="java" value-ref ="js" /> <entry key ="java2" value-ref ="js2" /> </map > </property > <property name ="sel" > <set > <ref bean ="js" /> <ref bean ="js2" /> </set > </property > </bean >
测试与上雷同
注解注入 使用注解注入可以不用set方法 但是需要扫描注解
扫描注解 <!--扫描注解 若没有则所有注解无效 某包的注解 包含子包 base-package="哪个包" --> <context:component-scan base-package="day2"></context:component-scan>
herdao
package day2;import java.sql.SQLException;import java.util.List;public interface HerDao { public List showAll () throws SQLException; }
HerDaoimpl
package day2;import org.springframework.stereotype.Repository;import java.sql.SQLException;import java.util.List;@Repository public class HerDaoimpl implements HerDao { @Override public List showAll () throws SQLException { System.out.println("HerDao取出英雄信息!" ); return null ; } }
service
package day2;import java.sql.SQLException;import java.util.List;public interface HerServices { public List showAll () throws SQLException; }
serviceimpl
package day2;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.sql.SQLException;import java.util.List;@Service public class HerServicesImpl implements HerServices { @Autowired HerDao he; @Override public List showAll () throws SQLException { he.showAll(); System.out.println("HerServices 完成业务!" ); return null ; } }
默认注解 默认为改类的第一个字母小写
自定义注解 @Repository("ck") @Autowired("...") @Service("fw")
配置 <context:component-scan base-package ="day2" > </context:component-scan >
测试 import day2.HerServices;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.sql.SQLException;public class springday2AnnotationsTest { @Test public void tesannon () throws SQLException { ClassPathXmlApplicationContext com=new ClassPathXmlApplicationContext ("spring-day2Annotations.xml" ); HerServices he= (HerServices) com.getBean("herServicesImpl" ); he.showAll(); } }
Spring junit jdbc 注:spring+junit整合 junit开启容器 JDBC连接数据库
启动容器的方法 1 、BeanFactory 2 、ClassPathXmlApplicationContext 3 、ApplicationContext
依赖 <dependency > <groupId > org.springframework</groupId > <artifactId > spring-context</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.11</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.16</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-test</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > commons-dbutils</groupId > <artifactId > commons-dbutils</artifactId > <version > 1.7</version > </dependency >
JDBC配置文件 JDBC.properties
jdbc.driv =com.mysql.cj.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/cctv?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false jdbc.usname =root jdbc.password =root
实体类 package com.it;public class Autos { public int id; public String cname; public String cnumber; public String ccolor; public int getId () { return id; } public void setId (int id) { this .id = id; } public String getCname () { return cname; } public void setCname (String cname) { this .cname = cname; } public String getCnumber () { return cnumber; } public void setCnumber (String cnumber) { this .cnumber = cnumber; } public String getCcolor () { return ccolor; } public void setCcolor (String ccolor) { this .ccolor = ccolor; } public Autos () { } public Autos (int id, String cname, String cnumber, String ccolor) { this .id = id; this .cname = cname; this .cnumber = cnumber; this .ccolor = ccolor; } @Override public String toString () { return "\nAutos{" + "id=" + id + ", cname='" + cname + '\'' + ", cnumber='" + cnumber + '\'' + ", ccolor='" + ccolor + '\'' + '}' ; } }
dao层 package com.it;import java.sql.SQLException;import java.util.List;public interface CarDao { public List seallCar () throws SQLException; }
dao层实现类 package com.it;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.sql.SQLException;import java.util.List;@Component public class CarDaoimpl implements CarDao { @Autowired QueryRunner runn; @Override public List seallCar () throws SQLException { String se="select * from autos" ; List lis=runn.query(se,new BeanListHandler <Autos>(Autos.class)); return lis; } }
service package com.it;import java.sql.SQLException;import java.util.List;public interface CatService { public List seallCar () throws SQLException; }
service实现类 serviceimpl
package com.it;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.sql.SQLException;import java.util.List;@Component public class CatServiceimpl implements CatService { @Autowired CarDao car; @Override public List seallCar () throws SQLException { List lis=car.seallCar(); System.out.println(lis); System.out.println("完成服务" ); return null ; } }
使用配置类 配置类:SpringConfig
package com.it;import com.alibaba.druid.pool.DruidDataSource;import org.apache.commons.dbutils.QueryRunner;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;@Configuration @ComponentScan(basePackages = "com.it") @PropertySource("classpath:JDBC.properties") public class SpringConfig { @Value("${jdbc.driv}") String driv; @Value("${jdbc.url}") String url; @Value("${jdbc.usname}") String usname; @Value("${jdbc.password}") String password; @Bean public QueryRunner runn (DataSource datasource) { QueryRunner runner=new QueryRunner (datasource); return runner; } @Bean public DataSource createDataSource () { DruidDataSource ds=new DruidDataSource (); ds.setDriverClassName(driv); ds.setUrl(url); ds.setUsername(usname); ds.setPassword(password); return ds; } }
使用spring+junit配置类测试 import com.it.CatService;import com.it.SpringConfig;import com.sun.org.apache.bcel.internal.util.ClassPath;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 java.sql.SQLException;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class SpringjunitTest { @Autowired CatService car; @Test public void test () throws SQLException { car.seallCar(); } }
直接测试不使用spring+junit测试 import day2.HerServices;import day2.SpringConfig;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import java.sql.SQLException;public class ConfigurationClassTest { @Test public void test1 () throws SQLException { ApplicationContext con=new AnnotationConfigApplicationContext (SpringConfig.class); HerServices he= (HerServices) con.getBean("herServicesImpl" ); he.showAll(); } }
使用配置文件 配置类 package com.it;import com.alibaba.druid.pool.DruidDataSource;import org.apache.commons.dbutils.QueryRunner;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;@Configuration @ComponentScan(basePackages = "com.it") @PropertySource("classpath:JDBC.properties") public class SpringConfig { @Value("${jdbc.driv}") String driv; @Value("${jdbc.url}") String url; @Value("${jdbc.usname}") String usname; @Value("${jdbc.password}") String password; @Bean public QueryRunner runn (DataSource datasource) { QueryRunner runner=new QueryRunner (datasource); return runner; } @Bean public DataSource createDataSource () { DruidDataSource ds=new DruidDataSource (); ds.setDriverClassName(driv); ds.setUrl(url); ds.setUsername(usname); ds.setPassword(password); return ds; } }
配置文件 spring.xml
<context:property-placeholder location ="classpath:JDBC.properties" />
<context:component-scan base-package ="com.it" > </context:component-scan >
<bean id ="createDataSource" class ="com.alibaba.druid.pool.DruidDataSource" destroy-method ="close" > <property name ="url" value ="${jdbc.url}" /> <property name ="driverClassName" value ="${jdbc.driv}" /> <property name ="username" value ="${jdbc.usname}" /> <property name ="password" value ="${jdbc.password}" /> </bean >
<bean id ="runn" class ="org.apache.commons.dbutils.QueryRunner" > <constructor-arg index ="0" ref ="createDataSource" > </constructor-arg > </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" 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 https://www.springframework.org/schema/context/spring-context.xsd" > <context:property-placeholder location ="classpath:JDBC.properties" /> <context:component-scan base-package ="com.it" > </context:component-scan > <bean id ="createDataSource" class ="com.alibaba.druid.pool.DruidDataSource" destroy-method ="close" > <property name ="url" value ="${jdbc.url}" /> <property name ="driverClassName" value ="${jdbc.driv}" /> <property name ="username" value ="${jdbc.usname}" /> <property name ="password" value ="${jdbc.password}" /> </bean > <bean id ="runn" class ="org.apache.commons.dbutils.QueryRunner" > <constructor-arg index ="0" ref ="createDataSource" > </constructor-arg > </bean > </beans >
SpringConfig 和 spring.xml
spring+junit配置文件测试 import com.it.CatService;import com.it.SpringConfig;import com.sun.org.apache.bcel.internal.util.ClassPath;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 java.sql.SQLException;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:spring.xml"}) public class SpringjunitTest { @Autowired CatService car; @Test public void test () throws SQLException { car.seallCar(); } }
注解解释 1 、@Component 和 @Bean 的区别@Bean 是方法返回new 对象 @Component 类返回@Repository 和 @Service 可以使用@Component 替换@Service 、@Repository 、@Component 、@Bean 、@Autowired 、@Configuration 、@ComponentScan 、@PropertySource 、@Value 、@RunWith 、@ContextConfiguration @Service :服务实现类添加 可以自定义(@Service ("自定义名称" )) 可以用@Component 替换@Repository :储存库 dao层实现类使用 可以有用@Component 替换 可以自定义(@Repository ("自定义名称" ))@Component :返回类 就是相当于new 一个类 返回该类 服务和dao实现类都可以使用 可以替换为@Service || @Repository @Bean :方法返回对象 把方法的返回值放到容器里面 相当于定对象@Autowired :自动注入 不需要set@Configuration :标注为配置类@ComponentScan :扫描包 ( @ComponentScan(basePackages = "包名") )@PropertySource :扫描配置文件 如xxx.properties 使用:(@PropertySource("classpath:文件名.properties") )@Value :赋值给某个属性 使用:@Value("${配置文件里的名称}") @RunWith :启动容器 使用:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration :使用配类的或者配置文件 有多个配置文件时需要使用{}(花括号)配置类:@ContextConfiguration(classes = 配置类的名称.class) 配置文件:@ContextConfiguration({"classpath:配置文件的名称.xml"}) @Aspect 切面@EnableAspectJAutoProxy 启动自动代理@Pointcut 切入点@Around 环绕通知@Before 之前通知@AfterReturning 最终通知@AfterThrowing 异常通知@After 最后通知@EnableTransactionManagement 开启事务@Transactional(propagation = Propagation.REQUIRED,readOnly = false) 添加事务@SessionAttributes({"goos"}) session@ResponseBody 返回JSon@RequestBody 接收参数为json@RequestMapping(path = "/goods",method = RequestMethod.GET) RequestMethod.GET 有get(查询)、post(添加)、put(修改)、delete(删除)@CrossOrigin 跨域@RequestHeader("token") 接收请求头身份@PathVariable("") 接收restful的路径参数@ControllerAdvice 控制器通知@ExceptionHandler(AjaxException.class) 异常解析器@Restcontroller = @Controller + @ResponseBody @GetMapper() 只接收get请求@Mapper 接口上@SpringBootApplication 扫描包+自动配置@SpringBootTest springboot测试
全配置文件配置 全配置文件和全配置都连接了数据库 依赖系统
依赖 <dependency > <groupId > org.springframework</groupId > <artifactId > spring-context</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.11</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.16</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-test</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > commons-dbutils</groupId > <artifactId > commons-dbutils</artifactId > <version > 1.7</version > </dependency >
<spring.version > 5.1.8.RELEASE</spring.version >
jdbc.properties jdbc.driv =com.mysql.cj.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/cctv?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false jdbc.usname =root jdbc.password =root
实体 package configclass;public class Car { public int id; public String cname; public String cnumber; public String ccolor; public int getId () { return id; } public void setId (int id) { this .id = id; } public String getCname () { return cname; } public void setCname (String cname) { this .cname = cname; } public String getCnumber () { return cnumber; } public void setCnumber (String cnumber) { this .cnumber = cnumber; } public String getCcolor () { return ccolor; } public void setCcolor (String ccolor) { this .ccolor = ccolor; } public Car () { } public Car (String cname, String cnumber, String ccolor) { this .cname = cname; this .cnumber = cnumber; this .ccolor = ccolor; } public Car (int id, String cname, String cnumber, String ccolor) { this .id = id; this .cname = cname; this .cnumber = cnumber; this .ccolor = ccolor; } @Override public String toString () { return "\nCar{" + "id=" + id + ", cname='" + cname + '\'' + ", cnumber='" + cnumber + '\'' + ", ccolor='" + ccolor + '\'' + '}' ; } }
dao package configfile;public class Car { public int id; public String cname; public String cnumber; public String ccolor; public int getId () { return id; } public void setId (int id) { this .id = id; } public String getCname () { return cname; } public void setCname (String cname) { this .cname = cname; } public String getCnumber () { return cnumber; } public void setCnumber (String cnumber) { this .cnumber = cnumber; } public String getCcolor () { return ccolor; } public void setCcolor (String ccolor) { this .ccolor = ccolor; } public Car () { } public Car (String cname, String cnumber, String ccolor) { this .cname = cname; this .cnumber = cnumber; this .ccolor = ccolor; } public Car (int id, String cname, String cnumber, String ccolor) { this .id = id; this .cname = cname; this .cnumber = cnumber; this .ccolor = ccolor; } @Override public String toString () { return "\nCar{" + "id=" + id + ", cname='" + cname + '\'' + ", cnumber='" + cnumber + '\'' + ", ccolor='" + ccolor + '\'' + '}' ; } }
daoimpl package configfile;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanListHandler;import javax.sql.DataSource;import java.sql.SQLException;import java.util.List;public class CarDaoimpl implements CarDao { QueryRunner runn; public void setRunn (QueryRunner runn) { this .runn = runn; } @Override public List SeAll () throws SQLException { String se="select * from autos" ; List lis=runn.query(se,new BeanListHandler <Car>(Car.class)); return lis; } }
service package configfile;import java.sql.SQLException;import java.util.List;public interface CarService { public List SeAll () throws SQLException; }
serviceimpl package configfile;import java.sql.SQLException;import java.util.List;public class CarServiceimpl implements CarService { CarDao cardao; public void setCardao (CarDao cardao) { this .cardao = cardao; } @Override public List SeAll () throws SQLException { List lis=cardao.SeAll(); System.out.println(lis); System.out.println("执行完成!" ); return null ; } }
配置文件 <?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 https://www.springframework.org/schema/context/spring-context.xsd" > <context:property-placeholder location ="classpath:jdbc.properties" > </context:property-placeholder > <context:component-scan base-package ="configfile" > </context:component-scan > <bean id ="datdasource" class ="com.alibaba.druid.pool.DruidDataSource" > <property name ="driverClassName" value ="${jdbc.driv}" > </property > <property name ="url" value ="${jdbc.url}" > </property > <property name ="username" value ="${jdbc.usname}" > </property > <property name ="password" value ="${jdbc.password}" > </property > </bean > <bean id ="runner" class ="org.apache.commons.dbutils.QueryRunner" > <constructor-arg index ="0" ref ="datdasource" > </constructor-arg > </bean > <bean id ="cardao" class ="configfile.CarDaoimpl" > <property name ="runn" ref ="runner" > </property > </bean > <bean id ="carse" class ="configfile.CarServiceimpl" > <property name ="cardao" ref ="cardao" > </property > </bean > </beans >
测试 import configfile.CarService;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.sql.SQLException;public class ConfigFlieTest { @Test public void test () throws SQLException { ClassPathXmlApplicationContext con=new ClassPathXmlApplicationContext ("spring.xml" ); CarService ca= (CarService) con.getBean("carse" ); ca.SeAll(); } }
全配置类配置 jdbc.properties和上面的一样 依赖也一致
实体 package configclass;public class Car { public int id; public String cname; public String cnumber; public String ccolor; public int getId () { return id; } public void setId (int id) { this .id = id; } public String getCname () { return cname; } public void setCname (String cname) { this .cname = cname; } public String getCnumber () { return cnumber; } public void setCnumber (String cnumber) { this .cnumber = cnumber; } public String getCcolor () { return ccolor; } public void setCcolor (String ccolor) { this .ccolor = ccolor; } public Car () { } public Car (String cname, String cnumber, String ccolor) { this .cname = cname; this .cnumber = cnumber; this .ccolor = ccolor; } public Car (int id, String cname, String cnumber, String ccolor) { this .id = id; this .cname = cname; this .cnumber = cnumber; this .ccolor = ccolor; } @Override public String toString () { return "\nCar{" + "id=" + id + ", cname='" + cname + '\'' + ", cnumber='" + cnumber + '\'' + ", ccolor='" + ccolor + '\'' + '}' ; } }
dao package configclass;import java.sql.SQLException;import java.util.List;public interface CarDao { public List SeAll () throws SQLException; }
daoimpl package configclass;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.sql.SQLException;import java.util.List;@Component public class CarDaoimpl implements CarDao { @Autowired QueryRunner runner; @Override public List SeAll () throws SQLException { String se="select * from autos" ; List lis=runner.query(se,new BeanListHandler <Car>(Car.class)); return lis; } }
service package configclass;import java.sql.SQLException;import java.util.List;public interface CarService { public List SeAll () throws SQLException; }
serviceimpl package configclass;import java.sql.SQLException;import java.util.List;public interface CarService { public List SeAll () throws SQLException; }
配置类 package configclass;import com.alibaba.druid.pool.DruidDataSource;import org.apache.commons.dbutils.QueryRunner;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;@Configuration @ComponentScan(basePackages = "configclass") @PropertySource("classpath:jdbc.properties") public class SpringConfig { @Value("${jdbc.driv}") String driv; @Value("${jdbc.url}") String url; @Value("${jdbc.usname}") String username; @Value("${jdbc.password}") String password; @Bean public QueryRunner createQueryRunner (DataSource dataSource) { QueryRunner runn=new QueryRunner (dataSource); return runn; } @Bean public DataSource createDataSource () { DruidDataSource ds=new DruidDataSource (); ds.setDriverClassName(driv); ds.setUrl(url); ds.setUsername(username); ds.setPassword(password); return ds; } }
测试 import configclass.CarService;import configclass.CarServiceimpl;import configclass.SpringConfig;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 java.sql.SQLException;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class ConfigClassTest { @Autowired CarService car; @Test public void test () throws SQLException { car.SeAll(); } }
AOP切面编程 动态代理 代理:使用代理对象, 是为了在不修改目标对象的基础上, 增强目标对象的业务逻辑.
JDK原生动态代理实例 接口
package day3;public interface IProducers { public void saleproducer (double money) ; }
实现类
package day3;public class Producers implements IProducers { @Override public void saleproducer (double money) { System.out.println("卖出一台电脑收到" + money +"元" ); } }
代理
package day3;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.logging.Level;public class Customer { public static void main (String[] args) { Producers Lenovo=new Producers (); ClassLoader clod=Lenovo.getClass().getClassLoader(); Class inter[]=Lenovo.getClass().getInterfaces(); IProducers dls= (IProducers) Proxy.newProxyInstance(clod, inter, new InvocationHandler () { @Override public Object invoke (Object proxy, Method method, Object[] args) throws Throwable { Object obj=null ; String mename=method.getName(); if ("saleproducer" .equals(mename)){ double mond= (double ) args[0 ]; System.out.println("代理商拿:" +mond * 0.2 ); obj=method.invoke(Lenovo,mond * 0.8 ); } return obj; } }); dls.saleproducer(10000 ); } }
spring文件配置动态代理 依赖
<!--AOP依赖--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
接口
package day3.aop;public interface AccountService { public void savemoney () ; public int atBank () ; }
目标对象类
package day3.aop.impl;import day3.aop.AccountService;public class AccountServiceImpl implements AccountService { @Override public void savemoney () { System.out.println("存钱成功!" ); } @Override public int atBank () { System.out.println("我去银行取钱!" ); return 0 ; } }
切面类
package day3.aop;public class BankingServices { public void vip () { System.out.println("存钱成功!送银行VIP一个月!" ); } public void car () { System.out.println("送车!" ); } }
配置文件 1、配置目标对象
2、配置切面对象
3、aop配置
第一个*是返回值 day3.aop..*.*(..)表示:day3包下面的aop包下面的所有类的所有方法 (..)表示多个构造方法的参数 expression="execution(* day3.aop..*save*(..))"
切面通知: 前置通知(before) 后置通知(after-returning) 异常通知(after-throwing) 最终通知(after) 环绕通知(可以阻止其他通知)
<!--通知 method="要哪个服务 服务的方法名" 前置通知(before) 后置通知(after-returning) 异常通知(after-throwing) 最终通知(after) 环绕通知(可以阻止其他通知) pointcut-ref="切入点的依赖"--> <aop:before method="vip" pointcut-ref="pt1"></aop:before> <aop:after-returning method="car" pointcut-ref="pt1"></aop:after-returning>
<?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 https://www.springframework.org/schema/aop/spring-aop.xsd" > <bean id ="Acserimpl" class ="day3.aop.impl.AccountServiceImpl" > </bean > <bean id ="BankSer" class ="day3.aop.BankingServices" > </bean > <aop:config > <aop:pointcut id ="pt1" expression ="execution(* day3.aop..*save*(..))" /> <aop:aspect id ="myqm" ref ="BankSer" > <aop:before method ="vip" pointcut-ref ="pt1" > </aop:before > <aop:after-returning method ="car" pointcut-ref ="pt1" > </aop:after-returning > </aop:aspect > </aop:config > </beans >
测试
package com.aop;import day3.aop.AccountService;import day3.aop.impl.AccountServiceImpl;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestAop { @Test public void test () { ClassPathXmlApplicationContext con=new ClassPathXmlApplicationContext ("spring-day3aop.xml" ); AccountService ac= (AccountService) con.getBean("Acserimpl" ); ac.savemoney(); } }
spring文件配置动态代理示例
接口
package aop;public interface HaveMealServices { public void eat () ; }
目标对象类
package aop.impl;import aop.HaveMealServices;public class HaveMealServicesImpl implements HaveMealServices { @Override public void eat () { System.out.println("刘盼盼正在吃饭!" ); } }
切面类
package aop;public class MotherLove { public void eatbefore () { System.out.println("饭前洗手!" ); } public void eatafter () { System.out.println("饭后洗碗!" ); } public void eatthow () { System.out.println("异常挨打!" ); } public void homework () { System.out.println("写作业!" ); } }
配置
<?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 https://www.springframework.org/schema/aop/spring-aop.xsd" > <bean id ="hase" class ="aop.impl.HaveMealServicesImpl" > </bean > <bean id ="molo" class ="aop.MotherLove" > </bean > <aop:config > <aop:pointcut id ="eat" expression ="execution(* aop.impl..*.*(..))" /> <aop:aspect id ="mlo" ref ="molo" > <aop:before method ="eatbefore" pointcut-ref ="eat" > </aop:before > <aop:after-returning method ="eatafter" pointcut-ref ="eat" > </aop:after-returning > <aop:after-throwing method ="eatthow" pointcut-ref ="eat" > </aop:after-throwing > <aop:after method ="homework" pointcut-ref ="eat" > </aop:after > </aop:aspect > </aop:config > </beans >
测试
import aop.HaveMealServices;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;public class AopTest { @Test public void test () { ClassPathXmlApplicationContext con=new ClassPathXmlApplicationContext ("spring.xml" ); HaveMealServices ha= (HaveMealServices) con.getBean("hase" ); ha.eat(); } }
AOP动态代理环绕通知
AOP使用注解
dao层
package aopclass;import org.springframework.stereotype.Component;public interface HaveMealServices { public void eat (int fen) ; }
daoimpl
package aopclass.impl;import aopclass.HaveMealServices;import org.springframework.stereotype.Component;@Component public class HaveMealServicesImpl implements HaveMealServices { @Override public void eat (int fen) { System.out.println("正在吃饭" +fen+" 分" ); } }
切面类
package aopclass;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Component @Aspect public class MotherLove { @Pointcut("execution(* aopclass..*.*(..))") public void p1 () { } @Before("p1()") public void eatbefore () { System.out.println("饭前洗手!" ); } @AfterReturning("p1()") public void eatafter () { System.out.println("饭后洗碗!" ); } @AfterThrowing("p1()") public void eatthow () { System.out.println("异常挨打!" ); } @After("p1()") public void homework () { System.out.println("写作业!" ); } @Around("p1()") public Object around (ProceedingJoinPoint jp) { Object obj=null ; Object[] num=jp.getArgs(); int number= (int ) num[0 ]; if (number>=60 ){ try { jp.proceed(); } catch (Throwable e) { e.printStackTrace(); } }else { System.out.println("拒绝执行" ); } return obj; } }
配置类
package aopclass;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.stereotype.Component;@Configuration @ComponentScan(basePackages = "aopclass") @EnableAspectJAutoProxy public class AspectConfiguration {}
测试(使用类测试类)
import aopclass.AspectConfiguration;import aopclass.HaveMealServices;import org.aspectj.apache.bcel.util.ClassPath;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(classes = AspectConfiguration.class) public class ClassTest { @Autowired HaveMealServices ha; @Test public void test () { ha.eat(80 ); } }
使用配置文件启动 配置文件
<?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" 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/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd" > <context:component-scan base-package ="aopclass" > </context:component-scan > <aop:aspectj-autoproxy > </aop:aspectj-autoproxy > </beans >
测试
import aopclass.AspectConfiguration;import aopclass.HaveMealServices;import org.aspectj.apache.bcel.util.ClassPath;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({"classpath:ConfigurationToStart.xml"}) public class ClassTest { @Autowired HaveMealServices ha; @Test public void test () { ha.eat(80 ); } }
SpringJDBC和事务 依赖 <spring.version > 5.1.8.RELEASE</spring.version >
<dependency > <groupId > org.springframework</groupId > <artifactId > spring-context</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-jdbc</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > com.alibaba</groupId > <artifactId > druid</artifactId > <version > 1.1.16</version > </dependency > <dependency > <groupId > commons-dbutils</groupId > <artifactId > commons-dbutils</artifactId > <version > 1.7</version > </dependency > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-test</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.11</version > </dependency > <dependency > <groupId > org.aspectj</groupId > <artifactId > aspectjweaver</artifactId > <version > 1.9.4</version > </dependency >
使用注解 jdbc配置文件 jdbc.properties
jdbc.driver =com.mysql.cj.jdbc.Driver jdbc.url =jdbc:mysql://localhost:3306/cctv?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false jdbc.username =root jdbc.password =root
实体entity package ConfigClass.bean;public class Deposit { public int id; public String name; public String iphone; public int fund; public int getId () { return id; } public void setId (int id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } public String getIphone () { return iphone; } public void setIphone (String iphone) { this .iphone = iphone; } public int getFund () { return fund; } public void setFund (int fund) { this .fund = fund; } public Deposit () { } public Deposit (String name, String iphone, int fund) { this .name = name; this .iphone = iphone; this .fund = fund; } public Deposit (int id, String name, String iphone, int fund) { this .id = id; this .name = name; this .iphone = iphone; this .fund = fund; } @Override public String toString () { return "\nDeposit{" + "id=" + id + ", name='" + name + '\'' + ", iphone='" + iphone + '\'' + ", fund=" + fund + '}' ; } }
dao层 package ConfigClass.dao;import ConfigClass.bean.Deposit;import java.util.List;public interface DepositDao { public List seall () ; public Deposit seonr (int id) ; public int deldep (int id) ; public int addde (Deposit de) ; public int upde (Deposit de) ; public int secoun () ; }
dao实现类impl package ConfigClass.dao.impl;import ConfigClass.bean.Deposit;import ConfigClass.dao.DepositDao;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Component;import java.util.List;@Component public class DepositDaoimpl implements DepositDao { @Autowired JdbcTemplate jdbcTemplate; @Override public List seall () { String se="select * from deposit" ; List lis=jdbcTemplate.query(se,new BeanPropertyRowMapper (Deposit.class)); return lis; } @Override public Deposit seonr (int id) { String se="select * from deposit where id=?" ; Deposit de=jdbcTemplate.queryForObject(se,new BeanPropertyRowMapper <Deposit>(Deposit.class),id); return de; } @Override public int deldep (int id) { String se="delete from deposit where id=?" ; int desu=jdbcTemplate.update(se,id); return desu; } @Override public int addde (Deposit de) { String se="insert into deposit(name,iphone,fund) values(?,?,?)" ; int adsu=jdbcTemplate.update(se,de.getName(),de.getIphone(),de.getFund()); return adsu; } @Override public int upde (Deposit de) { String se="update deposit set name=?,iphone=?,fund=? where id=?" ; Object[] obj=new Object [4 ]; obj[0 ]=de.getName(); obj[1 ]=de.getIphone(); obj[2 ]=de.getFund(); obj[3 ]=de.getId(); int upsu=jdbcTemplate.update(se,obj); return upsu; } @Override public int secoun () { String se="select count(*) from deposit" ; int coun=jdbcTemplate.queryForObject(se,Integer.class); return coun; } }
jdbc配置类 JdbcConfig
package ConfigClass;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.datasource.DataSourceTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;import javax.sql.DataSource;@Configuration @ComponentScan(basePackages = "ConfigClass") @PropertySource("classpath:jdbc.properties") @EnableTransactionManagement public class JdbcConfig { @Value("${jdbc.driver}") String driver; @Value("${jdbc.url}") String url; @Value("${jdbc.username}") String username; @Value("${jdbc.password}") String password; @Bean public DataSource createDataSource () { DruidDataSource ds=new DruidDataSource (); ds.setUsername(username); ds.setDriverClassName(driver); ds.setPassword(password); ds.setUrl(url); return ds; } @Bean public JdbcTemplate createjdbcTemplate (DataSource dataSource) { JdbcTemplate jd=new JdbcTemplate (dataSource); return jd; } @Bean public DataSourceTransactionManager cretasoman (DataSource dataSource) { DataSourceTransactionManager daman=new DataSourceTransactionManager (dataSource); return daman; } }
Service Service是一个转账的案例 但是调用上面的dao 支持事务
package ConfigClass.Service;public interface DepositService { public void Transfer (int forid,int Collection,int total) ; }
Serviceimpl package ConfigClass.Service;import ConfigClass.bean.Deposit;import ConfigClass.dao.DepositDao;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;@Service public class DepositServiceimpl implements DepositService { @Autowired DepositDao desiodao; @Override @Transactional(propagation = Propagation.REQUIRED,readOnly = false) public void Transfer (int forid, int Collection, int total) { Deposit de=desiodao.seonr(forid); Deposit de2=desiodao.seonr(Collection); if (de.getFund()<total){ System.out.println("余额不足!余额:" +de.getFund()); }else { Deposit yh=new Deposit (forid,de.getName(),de.getIphone(),de.getFund()-total); int z=desiodao.upde(yh); int bh=9 /0 ; Deposit dv=new Deposit (Collection,de2.getName(),de2.getIphone(),de2.getFund()+total); int h=desiodao.upde(dv); } } }
测试
import ConfigClass.JdbcConfig;import ConfigClass.Service.DepositService;import ConfigClass.bean.Deposit;import ConfigClass.dao.DepositDao;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 java.util.List;@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = JdbcConfig.class) public class ConfigClassTest { @Autowired DepositDao depdao; @Autowired DepositService deservic; @Test public void seall () { List li= depdao.seall(); System.out.println(li); } @Test public void seon () { Deposit de=depdao.seonr(1003 ); System.out.println(de); } @Test public void secoun () { int count=depdao.secoun(); System.out.println(count); } @Test public void del () { int de=depdao.deldep(1001 ); System.out.println(de); } @Test public void add () { Deposit de=new Deposit ("刘盼盼" ,"18709231456" ,8910 ); int ad=depdao.addde(de); System.out.println(ad); } @Test public void upda () { Deposit de=new Deposit (1002 ,"李兰" ,"16209241019" ,670 ); int up=depdao.upde(de); System.out.println(up); } @Test public void ServiceTest () { deservic.Transfer(1004 ,1003 ,10 ); } }
使用配置文件 jdbc配置文件与使用注解的配置相同
实体 package ConfigFilter.Bean;public class Deposit { public int id; public String name; public String iphone; public int fund; public int getId () { return id; } public void setId (int id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } public String getIphone () { return iphone; } public void setIphone (String iphone) { this .iphone = iphone; } public int getFund () { return fund; } public void setFund (int fund) { this .fund = fund; } public Deposit () { } public Deposit (String name, String iphone, int fund) { this .name = name; this .iphone = iphone; this .fund = fund; } public Deposit (int id, String name, String iphone, int fund) { this .id = id; this .name = name; this .iphone = iphone; this .fund = fund; } @Override public String toString () { return "\nDeposit{" + "id=" + id + ", name='" + name + '\'' + ", iphone='" + iphone + '\'' + ", fund=" + fund + '}' ; } }
dao层 package ConfigFilter.dao;import ConfigFilter.Bean.Deposit;import java.util.List;public interface DepositDao { public List seall () ; public Deposit seonr (int id) ; public int deldep (int id) ; public int addde (Deposit de) ; public int upde (Deposit de) ; public int secoun () ; }
daoimpl package ConfigFilter.dao.impl;import ConfigFilter.Bean.Deposit;import ConfigFilter.dao.DepositDao;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import java.util.List;public class DepositDaoimpl implements DepositDao { JdbcTemplate jdbcTemplate; public void setJdbcTemplate (JdbcTemplate jdbcTemplate) { this .jdbcTemplate = jdbcTemplate; } @Override public List seall () { String se="select * from deposit" ; List lis=jdbcTemplate.query(se,new BeanPropertyRowMapper (Deposit.class)); return lis; } @Override public Deposit seonr (int id) { String se="select * from deposit where id=?" ; Deposit de=jdbcTemplate.queryForObject(se,new BeanPropertyRowMapper <Deposit>(Deposit.class),id); return de; } @Override public int deldep (int id) { String se="delete from deposit where id=?" ; int desu=jdbcTemplate.update(se,id); return desu; } @Override public int addde (Deposit de) { String se="insert into deposit(name,iphone,fund) values(?,?,?)" ; int adsu=jdbcTemplate.update(se,de.getName(),de.getIphone(),de.getFund()); return adsu; } @Override public int upde (Deposit de) { String se="update deposit set name=?,iphone=?,fund=? where id=?" ; Object[] obj=new Object [4 ]; obj[0 ]=de.getName(); obj[1 ]=de.getIphone(); obj[2 ]=de.getFund(); obj[3 ]=de.getId(); int upsu=jdbcTemplate.update(se,obj); return upsu; } @Override public int secoun () { String se="select count(*) from deposit" ; int coun=jdbcTemplate.queryForObject(se,Integer.class); return coun; } }
Service package ConfigFilter.service;public interface DepositService { public void Transfer (int forid,int Collection,int total) ; }
Serviceimpl package ConfigFilter.service.impl;import ConfigFilter.Bean.Deposit;import ConfigFilter.dao.DepositDao;import ConfigFilter.service.DepositService;public class DepositServiceimpl implements DepositService { DepositDao desiodao; public void setDesiodao (DepositDao desiodao) { this .desiodao = desiodao; } @Override public void Transfer (int forid, int Collection, int total) { Deposit de=desiodao.seonr(forid); Deposit de2=desiodao.seonr(Collection); if (de.getFund()<total){ System.out.println("余额不足!余额:" +de.getFund()); }else { Deposit yh=new Deposit (forid,de.getName(),de.getIphone(),de.getFund()-total); int z=desiodao.upde(yh); int bh=9 /0 ; Deposit dv=new Deposit (Collection,de2.getName(),de2.getIphone(),de2.getFund()+total); int h=desiodao.upde(dv); System.out.println("转账成功!" ); } } }
配置文件 <tx:advice id ="txAdvice" transaction-manager ="datamang" > <tx:attributes > <tx:method name ="Tran*" propagation ="REQUIRED" read-only ="false" /> </tx:attributes > </tx:advice > <aop:config > <aop:advisor advice-ref ="txAdvice" pointcut ="execution(* ConfigFilter.service.impl.DepositServiceimpl.*(..))" > </aop:advisor > </aop:config >
<?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" xmlns:tx ="http://www.springframework.org/schema/tx" 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/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd" > <context:property-placeholder location ="classpath:jdbc.properties" > </context:property-placeholder > <context:component-scan base-package ="ConfigFilter" > </context:component-scan > <bean id ="datdasource" class ="com.alibaba.druid.pool.DruidDataSource" > <property name ="driverClassName" value ="${jdbc.driver}" > </property > <property name ="url" value ="${jdbc.url}" > </property > <property name ="username" value ="${jdbc.username}" > </property > <property name ="password" value ="${jdbc.password}" > </property > </bean > <bean id ="jdbctemp" class ="org.springframework.jdbc.core.JdbcTemplate" > <constructor-arg index ="0" ref ="datdasource" > </constructor-arg > </bean > <bean id ="datamang" class ="org.springframework.jdbc.datasource.DataSourceTransactionManager" > <constructor-arg index ="0" ref ="datdasource" > </constructor-arg > </bean > <tx:advice id ="txAdvice" transaction-manager ="datamang" > <tx:attributes > <tx:method name ="Tran*" propagation ="REQUIRED" read-only ="false" /> </tx:attributes > </tx:advice > <aop:config > <aop:advisor advice-ref ="txAdvice" pointcut ="execution(* ConfigFilter.service.impl.DepositServiceimpl.*(..))" > </aop:advisor > </aop:config > <bean id ="Deimpl" class ="ConfigFilter.dao.impl.DepositDaoimpl" > <property name ="jdbcTemplate" ref ="jdbctemp" > </property > </bean > <bean id ="servimpl" class ="ConfigFilter.service.impl.DepositServiceimpl" > <property name ="desiodao" ref ="Deimpl" > </property > </bean > </beans >
测试 import ConfigFilter.dao.DepositDao;import ConfigFilter.service.DepositService;import org.junit.Test;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;public class ConfigFliterTest { @Test public void test () { ClassPathXmlApplicationContext con=new ClassPathXmlApplicationContext ("spring.xml" ); DepositService se= (DepositService) con.getBean("servimpl" ); se.Transfer(1002 ,1003 ,10 ); } @Test public void testsel () { ClassPathXmlApplicationContext con=new ClassPathXmlApplicationContext ("spring.xml" ); DepositDao de= (DepositDao) con.getBean("Deimpl" ); List lis=de.seall(); System.out.println(lis); } }
SpringWebMVC 依赖 <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.0</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > <scope > provided</scope > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.9.8</version > </dependency >
配置spring.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" xmlns:mvc ="http://www.springframework.org/schema/mvc" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd" > <context:component-scan base-package ="springmvc" > </context:component-scan > <mvc:annotation-driven > </mvc:annotation-driven > <mvc:resources mapping ="/img/**" location ="/img/" > </mvc:resources > <mvc:resources mapping ="/css/**" location ="/css/" > </mvc:resources > <bean class ="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name ="prefix" value ="/WEB-INF/pages/" > </property > <property name ="suffix" value =".jsp" > </property > </bean > </beans >
配置web.xml <?xml version="1.0" encoding="UTF-8" ?> <web-app xmlns ="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version ="4.0" > <display-name > SpringMVC</display-name > <servlet > <servlet-name > mvc</servlet-name > <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class > <init-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:spring.xml</param-value > </init-param > </servlet > <servlet-mapping > <servlet-name > mvc</servlet-name > <url-pattern > /</url-pattern > </servlet-mapping > </web-app >
控制器Controller package springmvc.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controller public class HellController { @RequestMapping("/login") public String hello () { System.out.println("执行hello!" ); return "success" ; } @RequestMapping("/hero") public String heros () { System.out.println("执行heros" ); return "error" ; } @RequestMapping("/user") public ModelAndView senddate () { ModelAndView mv=new ModelAndView (); mv.setViewName("success" ); mv.addObject("meggage" ,"User执行成功!" ); return mv; } }
访问静态资源 如css img js…
配置spring.xml
location元素表示webapp目录下的包下的所有文件 mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b
<mvc:annotation-driven > </mvc:annotation-driven > <mvc:resources mapping ="/img/**" location ="/img/" > </mvc:resources > <mvc:resources mapping ="/css/**" location ="/css/" > </mvc:resources >
传值返回界面 @RequestMapping("/login") public String hello () { System.out.println("执行hello!" ); return "success" ; } @RequestMapping("/user") public ModelAndView senddate () { ModelAndView mv=new ModelAndView (); mv.setViewName("success" ); mv.addObject("meggage" ,"User执行成功!" ); return mv; }
依赖 -- mvc02包 <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.9.8</version > </dependency > 之前 <spring.version > 5.1.8.RELEASE</spring.version > <dependency > <groupId > org.springframework</groupId > <artifactId > spring-webmvc</artifactId > <version > ${spring.version}</version > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.0</version > <scope > provided</scope > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > <scope > provided</scope > </dependency > <dependency > <groupId > com.fasterxml.jackson.core</groupId > <artifactId > jackson-databind</artifactId > <version > 2.9.8</version > </dependency >
静态资源不被拦截 配置spring.xml
<mvc:annotation-driven > </mvc:annotation-driven > <mvc:default-servlet-handler > </mvc:default-servlet-handler >
字符串乱码 配置web.xml
<filter > <filter-name > charcode</filter-name > <filter-class > org.springframework.web.filter.CharacterEncodingFilter</filter-class > <init-param > <param-name > encoding</param-name > <param-value > UTF-8</param-value > </init-param > </filter > <filter-mapping > <filter-name > charcode</filter-name > <url-pattern > /*</url-pattern > </filter-mapping >
日期转换格式化
package springmvc.utlis;import org.springframework.core.convert.converter.Converter;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class MyDateConverter implements Converter <String, Date> { @Override public Date convert (String source) { SimpleDateFormat sdf=null ; Date da=null ; if (source.contains("年" )){ sdf=new SimpleDateFormat ("yyyy年MM月dd日" ); }else if (source.contains("-" )){ sdf=new SimpleDateFormat ("yyyy-MM-dd" ); }else if (source.contains("/" )){ sdf=new SimpleDateFormat ("yyyy/MM/dd" ); } try { da=sdf.parse(source); } catch (ParseException e) { e.printStackTrace(); } return da; } }
配置日期格式化 spring.xml
<bean id ="formattingConversion" class ="org.springframework.format.support.FormattingConversionServiceFactoryBean" > <property name ="converters" > <list > <mvc:annotation-driven conversion-service ="formattingConversion" > </mvc:annotation-driven >
html
<h1 > 表单测试</h1 > <form method ="get" action ="test1" > <input type ="text" name ="name" /> <input type ="text" name ="age" /> <input type ="date" name ="date" /> <button type ="submit" > 提交</button > </form >
控制器controller
@RequestMapping("/test1") public String test1 (String name, int age, Date date) { System.out.println("姓名:" +name); System.out.println("年龄:" +age); System.out.println("时间:" +date); return "success" ; }
表单得到对象 html
<h1 > 封装对象</h1 > <form method ="post" action ="test2" > <input type ="text" name ="name" /> <input type ="text" name ="age" /> <input type ="date" name ="date" /> <button type ="submit" > 提交</button > </form >
对象实体
package springmvc.entity;import java.util.Date;public class Student { public String name; public String age; public Date date; public String getName () { return name; } public void setName (String name) { this .name = name; } public String getAge () { return age; } public void setAge (String age) { this .age = age; } public Date getDate () { return date; } public void setDate (Date date) { this .date = date; } @Override public String toString () { return "Student{" + "name='" + name + '\'' + ", age='" + age + '\'' + ", date=" + date + '}' ; } }
控制器
@RequestMapping("/test2") public String test2 (Student stu) { System.out.println("对象:" +stu); return "success" ; }
表单得到List泛型 lis泛型是Goods的实体 Cart定义list
Goods实体
package springmvc.entity;public class Goods { String name; int num; public String getName () { return name; } public void setName (String name) { this .name = name; } public int getNum () { return num; } public void setNum (int num) { this .num = num; } @Override public String toString () { return "Goods{" + "name='" + name + '\'' + ", num='" + num + '\'' + '}' ; } }
Cart定义List
package springmvc.entity;import java.util.List;import java.util.Map;public class Cart { List<Goods> lis; Map<String,Goods> map; public List<Goods> getLis () { return lis; } public void setLis (List<Goods> lis) { this .lis = lis; } public Map<String, Goods> getMap () { return map; } public void setMap (Map<String, Goods> map) { this .map = map; } @Override public String toString () { return "Cart{" + "lis=" + lis + ", map=" + map + '}' ; } }
html
<h1 > List集合测试</h1 > <form method ="post" action ="test3" > <input type ="text" name ="lis[0].name" /> <input type ="text" name ="lis[0].num" /> <br > <input type ="text" name ="lis[1].name" /> <input type ="text" name ="lis[1].num" /> <br > <input type ="text" name ="lis[2].name" /> <input type ="text" name ="lis[2].num" /> <br > <button type ="submit" > 提交</button > </form >
控制器
@RequestMapping("/test3") public String test3 (Cart car) { System.out.println("List:" +car); return "success" ; }
表单得到map泛型 map与上面List一样 html不一样 一样使用list的Goods 和 Cart
<h1 > map集合测试</h1 > <form method ="post" action ="test3" > <input type ="text" name ="map['num1'].name" /> <input type ="text" name ="map['num1'].num" /> <br > <input type ="text" name ="map['num2'].name" /> <input type ="text" name ="map['num2'].num" /> <br > <input type ="text" name ="map['num3'].name" /> <input type ="text" name ="map['num3'].num" /> <br > <button type ="submit" > 提交</button > </form >
控制器
@RequestMapping("/test3") public String test3 (Cart car) { System.out.println("List:" +car); return "success" ; }
使用原来request response html
<h1 > requets response测试</h1 > <form method ="post" action ="test4" > <input type ="text" name ="name" /> <input type ="text" name ="age" /> <input type ="date" name ="date" /> <button type ="submit" > 提交</button > </form >
控制器
@RequestMapping("/test4") public void test4 (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String name=request.getParameter("name" ); String age=request.getParameter("age" ); String date=request.getParameter("date" ); System.out.println(name+" " + age +" " + date); HttpSession session=request.getSession(); ServletContext context=request.getServletContext(); response.sendRedirect("index.jsp" ); }
设置默认值 如果没有输入值则按默认值写入
html
<h1 > 默认值注解</h1 > <form method ="post" action ="anno/prama1" > <input type ="text" name ="name" /> <input type ="text" name ="age" /> <input type ="date" name ="date" /> <button type ="submit" > 提交</button > </form >
控制器 没有填值的时候就按默认的复制 @RequestParam(defaultValue = “内容” 类型=变量名)
package springmvc.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import springmvc.entity.Goods;@Controller @RequestMapping("/anno") public class AnnotationsController { @RequestMapping("/prama1") public String test1 (@RequestParam(defaultValue = "张三") String name,@RequestParam(defaultValue = "18") int age) { System.out.println(name +" " +age); return "success" ; } }
参数接收json 需要JSON解析包 在载jquery文件
html
<h1 > JSON传值 AJAX请求</h1 > <button type ="button" id ="cf" > JSON传值 AJAX请求</button > <script > $(function ( ) { var xm={"name" :"张胜男" ,"num" :19 }; $("#cf" ).click (function ( ) { $.ajax ({ url :'anno/prjson' , type :'post' , contentType :'application/json' , data :JSON .stringify (xm), success :function (data ) { alert (data); } }) }) }) </script >
控制器
package springmvc.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import springmvc.entity.Goods;@Controller @RequestMapping("/anno") public class AnnotationsController { @RequestMapping("/prjson") public String test2 (@RequestBody Goods gos) { System.out.println("json:" +gos); return "success" ; } }
Goods对象类
package springmvc.entity;public class Goods { String name; int num; public String getName () { return name; } public void setName (String name) { this .name = name; } public int getNum () { return num; } public void setNum (int num) { this .num = num; } @Override public String toString () { return "Goods{" + "name='" + name + '\'' + ", num='" + num + '\'' + '}' ; } }
四大作用域 返回json 四大作用域( page-request-session-application)
界面上如果不指定作用域的话,是先从小的作用域开始寻找
获取request的值 控制器
@RequestMapping("/put") public String put (ModelMap map) { map.put("cf" ,"触发" ); System.out.println("放入成功!" ); return "success" ; }
界面取值 requestScope:request范围
<h1 > request MOdelMap取值:${requestScope.cf}</h1 >
获取session的值 控制器
@RequestMapping("/put") public String put (ModelMap map) { map.put("cf" ,"触发" ); return "success" ; }
当设置session时需要指定ModelMap中的某个key为session
@SessionAttributes({"cf"})
界面
sessionScope为session范围
<h1 > session MOdelMap取值:${sessionScope.cf}</h1 >
获取application的值 控制器
@RequestMapping("/put") public String put (ModelMap map, HttpSession se) { ServletContext app=se.getServletContext(); app.setAttribute("cf" ,"applicationcontext触发!" ); return "success" ; }
界面 applicationScope为application范围
<h1 > application MOdelMap取值:${applicationScope.cf}</h1 >
四大作用域取值 @RequestMapping("/get") public String get (ModelMap mo) { String putval= (String) mo.get("cf" ); System.out.println(putval); return "success" ; }
销毁session 可以用来做退出登入
原来销毁session:se.invalidate()
@RequestMapping("/seremove") public String seremove (SessionStatus status) { System.out.println("退出登入!" ); status.setComplete(); return "success" ; }
路径参数 传统的网页传值方式:http://www.baidu?id=11…
新的传值:http://www.baidu/11… 把原来传统的id换成了/id数字
@RequestMapping("/plj/{movid}/{mvtype}") public String pramlj (@PathVariable("movid") String id,@PathVariable("mvtype") String type) { System.out.println("视频ID:" +id+" " +"视频类型:" +type); return "success" ; }
控制器返回JSON 返回json类
package springmvc.vo;public class JsonResult { int code; String msg; Object data; public int getCode () { return code; } public void setCode (int code) { this .code = code; } public String getMsg () { return msg; } public void setMsg (String msg) { this .msg = msg; } public Object getData () { return data; } public void setData (Object data) { this .data = data; } public JsonResult () { } public JsonResult (int code, String msg) { this .code = code; this .msg = msg; } public JsonResult (int code, String msg, Object data) { this .code = code; this .msg = msg; this .data = data; } @Override public String toString () { return "JsonResult{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + '}' ; } }
控制器 如果把@ResponseBody放到类上面则 整个类的所有方法都返回json
@RequestMapping("/retunjson") @ResponseBody public JsonResult returnjson () { List lis=new ArrayList (); lis.add("后羿" ); lis.add("李白" ); lis.add("嫦娥" ); JsonResult json=new JsonResult (200 ,"成功" ,lis); return json; }
ajax接收控制器返回的json <button id ="getsj" > AJAX得到数据</button > <script > $(function ( ) { $("#getsj" ).click (function ( ) { $.ajax ({ url :'anno/retunjson' , dataType :'json' , success : function (data ){ alert (data.msg ); alert (data.data [1 ]); } }) }); }) </script >
跨域注解 控制器
@CrossOrigin public JsonResult returnjson () { List lis=new ArrayList (); lis.add("后羿" ); lis.add("李白" ); lis.add("嫦娥" ); JsonResult json=new JsonResult (200 ,"成功" ,lis); return json; }
Restful设计 restful是路径参数 通过路径来执行对应的操作
POST 增加
GET 查询
DELETE 删除
PUT 更新
控制器
package springmvc.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import springmvc.entity.Student;@Controller public class RestfulController { @RequestMapping(path = "/student",method = RequestMethod.POST) public String add (Student st) { System.out.println("add" +st); return "success" ; } @RequestMapping(path = "/student/{sid}",method = RequestMethod.DELETE) public String del (@PathVariable("sid") int sid) { System.out.println("del " +sid); return "success" ; } @RequestMapping(path = "/student",method = RequestMethod.PUT) public String updat (Student st) { System.out.println("update " +st); return "success" ; } @RequestMapping(path = "/student",method = RequestMethod.GET) public String find () { System.out.println("find" ); return "success" ; } }
配置web.xml用来模拟delete 和 put请求
<filter > <filter-name > HiddenHttpMethodFliter</filter-name > <filter-class > org.springframework.web.filter.HiddenHttpMethodFilter</filter-class > </filter > <filter-mapping > <filter-name > HiddenHttpMethodFliter</filter-name > <url-pattern > /*</url-pattern > </filter-mapping >
界面 假请求 name=“_method(不可更改)” value=“你要的请求 如delete || put”
<%-- Created by IntelliJ IDEA. User: 羡羡 Date: 2021/10/29 Time: 9:34 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html > <head > <title > 测试Restful</title > </head > <body > <h1 > 测试增加</h1 > <form method ="post" action ="student" > <input type ="text" name ="name" /> <input type ="text" name ="age" /> <input type ="date" name ="date" /> <button type ="submit" > 提交</button > </form > <hr > <h1 > 测试查询</h1 > <form method ="get" action ="student" > <button type ="submit" > 提交</button > </form > <hr > <h1 > 测试删除</h1 > <form method ="post" action ="student/101" > <input type ="hidden" name ="_method" value ="DELETE" /> <button type ="submit" > 提交</button > </form > <hr > <h1 > 测试更新</h1 > <form method ="post" action ="student" > <input type ="hidden" name ="_method" value ="PUT" /> <input type ="text" name ="name" /> <input type ="text" name ="age" /> <input type ="date" name ="date" /> <button type ="submit" > 提交</button > </form > </body > </html >
注意
当使用tomcat7.0 以上时 需要在要跳转的界面加入 isReeorPage="true" <%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
return重定向 return "success" ;return "redirect:index.jsp" ;
控制器//成功后重定向到index.jsp
@RequestMapping("/ptlogin") public String ptlogin (String name,String pass) { if ("admin" .equals(name) && "admin" .equals(pass)){ return "redirect:index.jsp" ; }else { return "error" ; } }
Restful Ajax请求 控制器
package springmvc.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import springmvc.entity.Student;@Controller public class RestfulController { @RequestMapping(path = "/student",method = RequestMethod.POST) public String add (Student st) { System.out.println("add" +st); return "success" ; } @RequestMapping(path = "/student/{sid}",method = RequestMethod.DELETE) public String del (@PathVariable("sid") int sid) { System.out.println("del " +sid); return "success" ; } @RequestMapping(path = "/student",method = RequestMethod.PUT) public String updat (Student st) { System.out.println("update " +st); return "success" ; } @RequestMapping(path = "/student",method = RequestMethod.GET) public String find () { System.out.println("find" ); return "success" ; } }
界面请求
<%-- Created by IntelliJ IDEA. User: 羡羡 Date: 2021/10/29 Time: 10:36 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html > <head > <title > RestfulAjax请求</title > <script src ="js/jquery-1.10.2.js" > </script > <script > $(function ( ) { $("#add" ).click (function ( ){ $.ajax ({ url :'student' , type :'post' , data :{ "name" :"张三" , "age" :"19" , "date" :"2021-10-12" }, success :function (data ){ alert (data); } }) }) $("#del" ).click (function ( ){ $.ajax ({ url :'student/101' , type :'delete' , success :function (data ){ alert (data); } }) }) $("#upda" ).click (function ( ){ $.ajax ({ url :'student' , type :'post' , data :{ "name" :"张三" , "age" :"19" , "date" :"2021-10-12" , "_method" :"PUT" }, success :function (data ){ alert (data); } }) }) $("#sel" ).click (function ( ){ $.ajax ({ url :'student' , type :'get' , success :function (data ){ alert (data); } }) }) }) </script > </head > <body > <button type ="button" id ="add" > 添加</button > <button type ="button" id ="del" > 删除</button > <button type ="button" id ="upda" > 修改</button > <button type ="button" id ="sel" > 查询</button > </body > </html >
身份验证 请求头 控制器
用来前后端分离身份验证
@RequestMapping("/headajaxlogin") @ResponseBody public String ajaxlogin (@RequestHeader("token") String token,String name, int age) { System.out.println("请求头:" +token); System.out.println("姓名:" +name); System.out.println("年龄:" +age); return "success" ; }
界面
<h1 > 身份信息</h1 > <button id ="fas" > 发送请求信息</button > <script > $("#fas" ).click (function ( ){ $.ajax ({ type :'post' , url :'headajaxlogin' , headers :{'token' :'12121021' }, data :{ "name" :"张三" , "age" :18 }, success :function (data ) { alert (data); } }) }); </script >
全局异常 当ajax错误 或者java代码错误试跳到指定界面
定义ajax异常
package springmvc.execption;public class AjaxExecption extends Exception { public AjaxExecption (String message) { super (message); } }
全局系统异常解析器
package springmvc.execption;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.stereotype.Component;import org.springframework.web.servlet.HandlerExceptionResolver;import org.springframework.web.servlet.ModelAndView;import springmvc.vo.JsonResult;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.OutputStream;import java.io.PrintWriter;import java.io.Writer;@Component public class SysExecptionResolver implements HandlerExceptionResolver { ObjectMapper objectMapper = new ObjectMapper (); @Override public ModelAndView resolveException (HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView mv=new ModelAndView (); if (e instanceof AjaxExecption){ JsonResult json=new JsonResult (500 ,e.getMessage()); ajaxexecption(json,httpServletResponse); }else { mv.addObject("msg" ,e.getMessage()); mv.setViewName("execptionpage" ); } return mv; } private void ajaxexecption (JsonResult json,HttpServletResponse response) { String js= null ; try { js = objectMapper.writeValueAsString(json); response.setContentType("application/json;charset=UTF-8" ); PrintWriter pr=response.getWriter(); pr.write(js); pr.flush(); pr.close(); } catch (JsonProcessingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
ajax请求错误控制器
@RequestMapping("/retunjson") @ResponseBody @CrossOrigin public JsonResult returnjson () throws AjaxExecption { List lis=new ArrayList (); lis.add("后羿" ); lis.add("李白" ); lis.add("嫦娥" ); try { int f=9 /0 ; }catch (Exception e){ throw new AjaxExecption ("JSON错误!" ); } JsonResult json=new JsonResult (200 ,"成功" ,lis); return json; }
上面类的返回对象JsonResult是处理json的类 JsonResult
package springmvc.vo;public class JsonResult { int code; String msg; Object data; public int getCode () { return code; } public void setCode (int code) { this .code = code; } public String getMsg () { return msg; } public void setMsg (String msg) { this .msg = msg; } public Object getData () { return data; } public void setData (Object data) { this .data = data; } public JsonResult () { } public JsonResult (int code, String msg) { this .code = code; this .msg = msg; } public JsonResult (int code, String msg, Object data) { this .code = code; this .msg = msg; this .data = data; } @Override public String toString () { return "JsonResult{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + '}' ; } }
普通控制器报错 这个控制器是测试上面的全局异常
@RequestMapping("/login") public String hello () { System.out.println("执行hello!" ); int f=9 /0 ; return "redirect:index.jsp" ; }
全局异常(新) ajax异常类
package ssm1.config;public class AjaxException extends Exception { public AjaxException (String message) { super (message); } }
普通异常类
package ssm1.config;public class NormalException extends Exception { public NormalException (String message) { super (message); } }
全局异常处理类
package ssm1.config;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.servlet.ModelAndView;@ControllerAdvice public class { @ExceptionHandler(NormalException.class) public ModelAndView handleNormal (NormalException ex) { ModelAndView mv=new ModelAndView (); mv.addObject("errmsg" ,"自定义错误" +ex.getMessage()); mv.setViewName("Erroe" ); return mv; } @ExceptionHandler(AjaxException.class) @ResponseBody public JsonResultSet handleAjax (AjaxException ex) { System.out.println("异常" ); JsonResultSet ok=new JsonResultSet (500 ,ex.getMessage()); return ok; } }
普通错误异常控制器
@RequestMapping("/hello") public String seall (ModelMap map,int n) throws NormalException { List lsi=deser.getDeList(); try { int h=9 /n; }catch (Exception e){ throw new NormalException (e.getMessage()); } map.put("info" ,lsi); return "Hello" ; }
ajax错误异常控制器
@RequestMapping("/json") @ResponseBody public JsonResultSet de (int n) throws AjaxException { Deposit de=new Deposit (1005 ,"化解" ,"121213113" ,800 ); JsonResultSet js; try { js=new JsonResultSet (200 ,"成功" ,de); int h=9 /n; }catch (Exception e){ throw new AjaxException (e.getMessage()); } return js; }
404异常处理 配置web.xml
<error-page > <error-code > 404</error-code > <location > /WEB-INF/pages/err404.jsp</location > </error-page >
spring文件上传 依赖
<!--文件上传--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency>
spring.xml配置
<bean id ="multipartResolver" class ="org.springframework.web.multipart.commons.CommonsMultipartResolver" > <property name ="maxUploadSize" value ="10485760" /> </bean >
上传控制器 上传的路径的文件夹必须先要有东西
@RequestMapping("/filupload") public String upload (HttpServletRequest request, MultipartFile[] multipart) throws IOException { String path=request.getRealPath("/img/" ); System.out.println(path); for (MultipartFile file : multipart){ String fname=file.getOriginalFilename(); System.out.println(fname); file.transferTo(new File (path,fname)); } return "success" ; }
界面
<form action ="filupload" method ="post" enctype ="multipart/form-data" > <input type ="file" name ="multipart" /> <button type ="submit" > 提交</button > </form >
ajax spring文件上传 依赖和配置和spring文件上传一致
控制器
@RequestMapping("/ajaflie") @ResponseBody public JsonResult ajupload (HttpServletRequest request, MultipartFile[] multipart) throws IOException { JsonResult js = null ; String path=request.getRealPath("/img/" ); System.out.println(path); for (MultipartFile file : multipart){ String fname=file.getOriginalFilename(); System.out.println(fname); file.transferTo(new File (path,fname)); js=new JsonResult (200 ,"成功" ,fname); } return js; }
返回类型JsonResult是一个类Spring Json统一格式 界面
js <script > function jqfile ( ){ var formData = new FormData (); formData.append ('multipart' , $('#file' )[0 ].files [0 ]); $.ajax ({ url : 'ajaflie' , type : 'POST' , cache : false , data : formData, processData : false , contentType : false , dataType : 'json' , success : function (res ){ $("#file" ).val ("" ); $("#cf" ).attr ("src" ,"img/" +res.data ); } }); } </script > ----------------------------- html <h1 > Ajax上传</h1 > <input type ="file" name ="multipart" id ="file" /> <button onclick ="jqfile()" > 上传</button > <br > <img alt ="图片" id ="cf" />
云储存spring文件上传 依赖
<dependency > <groupId > commons-fileupload</groupId > <artifactId > commons-fileupload</artifactId > <version > 1.3.2</version > </dependency > <dependency > <groupId > com.qcloud</groupId > <artifactId > cos_api</artifactId > <version > 5.6.54</version > </dependency > <dependency > <groupId > org.slf4j</groupId > <artifactId > slf4j-simple</artifactId > <version > 1.7.25</version > </dependency > <dependency > <groupId > log4j</groupId > <artifactId > log4j</artifactId > <version > 1.2.17</version > </dependency >
配置文件 log4j.properties
log4j.rootLogger =debug, stdout, R log4j.appender.stdout =org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout =org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern =%5p [%t] (%F:%L) - %m%n log4j.appender.R =org.apache.log4j.RollingFileAppender log4j.appender.R.File =example.log log4j.appender.R.MaxFileSize =100KB log4j.appender.R.MaxBackupIndex =5 log4j.appender.R.layout =org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern =%p %t %c - %m%n
上传删除下载配置类
package springmvc.utlis;import com.fasterxml.jackson.databind.ObjectMapper;import com.qcloud.cos.COSClient;import com.qcloud.cos.ClientConfig;import com.qcloud.cos.auth.BasicCOSCredentials;import com.qcloud.cos.auth.COSCredentials;import com.qcloud.cos.model.GetObjectRequest;import com.qcloud.cos.model.ObjectMetadata;import com.qcloud.cos.model.PutObjectRequest;import com.qcloud.cos.region.Region;import java.io.File;import java.io.InputStream;public class CosFileupload { public static String SECRET_ID="CwPbW" ; public static String SECRET_KEY="P6XhbMq" ; public static String BUCKETNAME="sls" ; public static String REGIONID="ap-guangzhou" ; public static COSClient Initialize () { COSCredentials cred = new BasicCOSCredentials (SECRET_ID, SECRET_KEY); ClientConfig clientConfig = new ClientConfig (new Region (REGIONID)); COSClient cosClient = new COSClient (cred, clientConfig); return cosClient; } public static void upfile (InputStream Inputstream, String key) { COSClient cosin=CosFileupload.Initialize(); ObjectMetadata metadata=new ObjectMetadata (); PutObjectRequest request=new PutObjectRequest (BUCKETNAME,key,Inputstream,metadata); cosin.putObject(request); System.out.println(request); cosin.shutdown(); } public static void downloadfile (File file,String key) { File dowfile=new File (file+"\\" +key); GetObjectRequest getobjrequest=new GetObjectRequest (BUCKETNAME,key); COSClient cosdowfile=CosFileupload.Initialize(); cosdowfile.getObject(getobjrequest,dowfile); cosdowfile.shutdown(); } public static void delfile (String key) { COSClient cosdelfile=CosFileupload.Initialize(); cosdelfile.deleteObject(BUCKETNAME,key); cosdelfile.shutdown(); } }
控制器
@RequestMapping("/TencentCloudFileUpload") public String tencos (MultipartFile[] multipart, ModelMap map) throws IOException { for (MultipartFile file : multipart){ String fname=file.getOriginalFilename(); Long time=System.currentTimeMillis(); int wz=fname.lastIndexOf("." ); String filna=fname.substring(wz+1 ); System.out.println("后缀名:" +filna); String pna=time+"." +filna; System.out.println("图片名:" +pna); try { CosFileupload.upfile(file.getInputStream(),pna); map.put("imglj" ,"https://sls-study-cloud-1301165591.cos.ap-guangzhou.myqcloud.com/" +pna); }catch (Exception e) { System.out.println("上传失败!" ); } } return "redirect:springfliload.jsp" ; }
界面 文件输入框的name需要和控制器的MultipartFile数组的变量名相同
<h1 > 云储存上传</h1 > <form action ="TencentCloudFileUpload" method ="post" enctype ="multipart/form-data" > <input type ="file" name ="multipart" /> <input type ="submit" /> </form > <img src ="${imglj}" alt ="云储存" />
路径不能直接显示 <base href ="http://localhost:8090/SpringMVC/" >
动态获取项目路径 <base href ="${pageContext.request.getScheme()}://${pageContext.request.getServerName()}:${pageContext.request.getServerPort()}${pageContext.request.contextPath}/" />
拦截器 多个拦截器顺序
拦截所有
package springmvc.Interceptor;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class HelloInterceptor implements HandlerInterceptor { @Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("A1:拦截前运行!" +handler); return true ; } @Override public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("A2:拦截运行中!" +handler); System.out.println("视图:" +modelAndView.getViewName()); modelAndView.addObject("cf" ,"spring拦截器!" ); modelAndView.setViewName("err404" ); } @Override public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("A3:拦截后!" +handler); } }
配置spring.xml(拦截所有)
<mvc:interceptors > <mvc:interceptor > < !– /**就是拦截所有– > <mvc:mapping path ="/**" /> < !– 执行拦截的类– > <bean class ="springmvc.Interceptor.HelloInterceptor" > </bean > </mvc:interceptor > </mvc:interceptors >
配置拦截某个位置spring.xml 拦截anno下面的所有 配置路径就是 /anno/**
<mvc:interceptors > <mvc:interceptor > < !– /anno/**就是拦截anno下的所有 anno在AnnotationsController– > <mvc:mapping path ="/anno/**" /> < !– 执行拦截的类– > <bean class ="springmvc.Interceptor.AnnoInterceptor" > </bean > </mvc:interceptor > </mvc:interceptors >
配置拦截到某个控制器spring.xml
<mvc:interceptors > <mvc:interceptor > <mvc:mapping path ="/vip/**" /> <bean class ="springmvc.Interceptor.GameInterceptor" > </bean > </mvc:interceptor > </mvc:interceptors >
登入拦截示例 配置spring.xml
<mvc:interceptors > <mvc:interceptor > <mvc:mapping path ="/vip/**" /> <bean class ="springmvc.Interceptor.GameInterceptor" > </bean > </mvc:interceptor > </mvc:interceptors >
控制器
package springmvc.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.SessionAttributes;import org.springframework.web.bind.support.SessionStatus;@Controller @SessionAttributes({"login"}) public class GameLogin { @RequestMapping("/gamelogon") public String login (String name, String pass, ModelMap map) { map.put("login" ,name); return "success" ; } @RequestMapping("/vip/game") public String game () { System.out.println("正在游戏!" ); return "success" ; } @RequestMapping("/exlog") public String exit (SessionStatus sruts) { sruts.setComplete(); return "redirect:gamelogin.jsp" ; } }
拦截器
package springmvc.Interceptor;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class GameInterceptor implements HandlerInterceptor { @Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String name= (String) request.getSession().getAttribute("login" ); System.out.println(name); if (name!=null ){ return true ; }else { response.sendRedirect("/SpringMVC/gamelogin.jsp" ); return false ; } } @Override public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super .afterCompletion(request, response, handler, ex); } }
所有注解 @Override 重写@Repository DAO层实现类上 = <bean id="类名首字母小写" >@Service 服务层@Controller 控制器和成一个 @Component @Autowired 自动注入 类似set@Bean 把方法返回值放入容器@PropertySource("classpath:jdbc8.properties") @Value("${key}") 读取配置文件key@ComponentScan 扫描包里带注解的对象@Configuration 这是个配置类== AOP相关注解 === @Aspect 切面切入点 @Pointcut("execution(* day3.homework.*.*(..))") 环绕通知 @Around 前置 @Before 后置 @After -returning 异常 @After -throwing 最终 @After @EnableTransactionManagement 事务管理器@Transactional 事务== SpringMVC 相关注解 === @RequestMapping("/hello") @RequestParam @RequestBody 参数可以是JSON对象@ResponseBody 返回JSON @RequestMapping("/douban/{mtype}/{movieid}") @PathVariable("movieid") @SessionAttributes("food") @CrossOrigin @RequestHeader("token") RESTFUL 请求 get,post,put ,delete @RequestMapping(path = "/student",method = RequestMethod.PUT) @ControllerAdvice 控制器通知@ExceptionHandler(AjaxException.class) @RestController = @Controller + @ResponseBody @GetMapping("/world") @Mapper 接口上@SpringBootApplication 扫包,自动配置@SpringBootTest