除了自己,没人可以为快乐负责
文章目录
Spring
1.spring的优势
-
方便解耦,简化开发
通过Spring提供的 loC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。 -
Aop编程的支持
通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统ОOP实现的功能可以通过AOP轻松实现。 -
声明式事务的支持
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。 -
简单的步骤
导入Spring开发的基本包坐标 编写 Dao接口和实现类 创建Spring核心配置文件 在Spring配置文件中配置UserDaolmpl 使用Spring的API获得Bean 实例
2.初识控制反转
将创建类的对象的权利交给容器
配置文件
<bean id="dao"/**唯一标识**/ class="spring.Dao.impl.Daoimpl/**类的全包名**/"></bean>
demo类中
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
Daoimpl dao = (Daoimpl) app.getBean("dao");
dao.run();
Bean标签的其他属性
:scope
scope | |
---|---|
singleton | 默认,单例的; 当bean是单例模式的时候,在加载配置文件的时候spring容器就已经给所有是单例模式的类创建了一个对象 |
prototype | 多例的 ;当bean是多例模式的时候,只有在用户getBean的时候才会创建一个对象 |
request | WEB项目中,Spring创建一个Bean的对象,将对象存入到request 域中 |
session | WEB项目中,Spring创建一个Bean的对象,将对象存入到session 域中 |
global session | wEB项目中,应用在Portlet环境,如果没有Portlet环境那么globalSession相当于session |
Bean标签的生命周期属性配置
- init-method:指定被管理的类的初始化方法
- destory-method:指定被管理的类的销毁方法,不过需要手动关闭不然会来不及执行
Bean实例化的三种方式
-
无参构造方法实例化
-
工厂静态方法实例化
public class Daoimpl implements springDao { public void run() { System.out.println("dao运行起来了"); } public static Daoimpl factoryDao(){ return new Daoimpl();//这是静态工厂方法 }//当然这里也可以是其他类的静态方法返回当前类的实例对象,如jdbc的getConnection等等 } 配置文件 <bean id="dao" class="spring.Dao.impl.Daoimpl" factory-method="factoryDao"></bean>
-
工厂实例方法实例化
public class Daoimpl implements springDao { public void run() { System.out.println("dao运行起来了"); } } public class Daofactory { public Daoimpl factoryDao(){ System.out.println("工厂静态方法"); return new Daoimpl(); } } !!!!这个时候工厂方法不能放在需要创建的类里面,因为如果放里面的话,要求先有实例才能调用工厂方法,而第一个实例只能由构造函数创建 ps:这里与静态方法不同的是,必须先拥有当前对象才能调用对象的工厂方法 配置文件 <bean id="daofactory" class="spring.Dao.impl.Daofactory"></bean>//因为不是静态方法所以要先创建工厂类的实例对象, <bean id="dao" class="spring.Dao.impl.Daoimpl" factory-bean="daofactory" factory-method="factoryDao" ></bean>
依赖注入
- 在不使用依赖注入的方式的时候,要搭建三层架构,是在serive层由程序员向spring容器要dao层实例,而在web层又向spring容器要service层实例
使用依赖注入的方式,因为service和dao都在Spring容器之中,而程序只需要service,所以在spring容器中,将dao层直接设置到service层内部
两种方式
-
set方法
配置文件 <bean id="dao" class="spring.Dao.impl.Daoimpl"></bean> <bean id="service" class="spring.Servive.impl.ServiceImpl"> <property name="daoo"/**构造方法去掉set首字母小写**/ ref="dao"/**引用dao唯一id**/> </property> </bean> ------------------------ service层 public class ServiceImpl implements springService { private Daoimpl dao; public void setDaoo(Daoimpl dao) { this.dao = dao; } public void save() { System.out.println("service开始运行dao"); dao.run(); } } ----------- web层用getBean只调用service就行了
简化配置文件引入p命名空间
<bean id="dao" class="spring.Dao.impl.Daoimpl"></bean> <bean id="service" class="spring.Servive.impl.ServiceImpl" p:daoo-ref="dao"> </bean>
-
构造方法
<bean id="service" class="spring.Servive.impl.ServiceImpl"> <constructor-arg name="dao"/**构造函数的参数名**/ ref="dao"></constructor-arg> </bean> ------------ service层 同上加一个有参构造方法 public ServiceImpl(Daoimpl dao) { this.dao = dao; }
其他数据类型的注入
-
普通数据类型
配置文件 <bean id="service" class="spring.Servive.impl.ServiceImpl" p:daoo-ref="dao" p:username="雷锋"> </bean> ---------------- private String username;service类的成员变量
-
引用或者集合数据类型
配置文件 <bean id="service" class="spring.Servive.impl.ServiceImpl" p:daoo-ref="dao" p:username="雷锋" > <property name="list"> <list> <value>aaa</value> <value>bbb</value> </list> </property> </bean> ---------- private ArrayList list;
相关API
-
ApplicationContext的实现类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rujxkCwn-1661235847068)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220719232841773.png)]
-
getBean
参数 id或者类的class字节码文件
如果一个类只会使用一个而不是多个可以使用类的class参数,反之不行
配置数据源
C3p0的配置
------
不使用依赖之前的代码
ComboPooledDataSource c3 = new ComboPooledDataSource();
c3.setDriverClass("com.mysql.jdbc.Driver");
c3.setJdbcUrl("jdbc:mysql://localhost:3306/zf1");
c3.setUser("root");
c3.setPassword("root");
Connection connection = c3.getConnection();
System.out.println(connection);
---------------------
配置文件
<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/zf1"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
-----------------
spring容器加载properties文件
<context:properties-placeholder location="xx.properties" />
<bean
<property name="xxx" value='${key}'
</bean>
注解开发
-
Spring原始注解
注解 说明 @Component 使用在类上用于实例化Bean @Controller 使用在web层类上用于实例化Bean使用 @Service 在service层类上用于实例化Bean使用 @Repository 在dao层类上用于实例化Bean @Autowired 使用在字段上用于根据类型从spring容器中进行依赖注入 @Qualifier 必须结合@Autowired—起使用用于根据唯一id进行依赖注入 @Resource 相当于@Autowired+@Qualifier,按照唯一id进行注入 @Value 注入普通属性,通常配合${key}使用 @Scope 标注Bean的作用范围 @PostConstruct 使用在方法上标注该方法是Bean的初始化方法 @PreDestroy 使用在方法上标注该方法是Bean的销毁方法 -
新注解
注解 说明 @Configuration 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 @ComponentScan 用于指定Spring在初始化容器时要扫描的包作用一样 @Bean 一样使用在方法上,标注将该方法的返回值存储到Spring容器中 @PropertySource 用于加载.properties文件中的配置 @Import 用于导入其他配置类 配置抽取为配置类
@PropertySource("jdbc.properties") @ComponentScan("spring") @Configuration public class configs { @Value("${driverClassName}") private String ClassName; @Value("${url}") private String Url; @Value("${jdbcusername}") private String userName; @Value("${password}") private String password; private DruidDataSource dataSource; @Bean("datasource") public DataSource getDataSource(){ dataSource = new DruidDataSource(); dataSource.setDriverClassName(ClassName); dataSource.setUrl(Url); dataSource.setUsername(userName); dataSource.setPassword(password); return dataSource; } }
spring集成web
初识
ApplicationContext app = new AnnotationConfigApplicationContext("spring");
Serviceimpl service = app.getBean(Serviceimpl.class);
service.save();
------//当spring在web的三层架构之中运行的时ApplicationContext app = new AnnotationConfigApplicationContext("spring");
Serviceimpl service = app.getBean(Serviceimpl.class);
service.save();
------//当spring在web的三层架构之中运行的时候,在web层按照以往的知识都会写出如上代码
ApplicationContext又叫做应用上下文对象,如果太多的如上代码就会造成配置文件被加载多次,应用上下文对象被创建多次
---------解决方法:定义一个servlet监听器,
public class springTestListen implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
ApplicationContext app = new AnnotationConfigApplicationContext("spring");
/**对于上述的参数也可以抽成配置文件,web.xml是一个好的选择,在servlet初始化参数可以配置创建spring容器要传递的参数***/
ServletContext servletContext = servletContextEvent.getServletContext();
servletContext.setAttribute("app",app);
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
----------------官方提供的
1.配置ContextLoaderListener(官方提供)
在web.xml中配置监听器
<context-param>
<param-name>
contextConfigLocation
</param-name>
<param-value>
classpath:**/*Context.xml
</param-value>
</context-param>
<listener>
<listener class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>***/
--------java类方式配置--------------------------------------------
ps. 使用类继承WebApplicationInitializer
public class springTestListen implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext Context) throws ServletException {
Context.addListener(new ContextLoaderListener());
// Context.addListener(new WebAppRootListener());
Context.setInitParameter("contextConfigLocation", "classpath:**/*Context.xml");
}
}
2.使用WebApplicationContextUtils获取应用上下文对象
-----------------------无xml配置
2.无xml的方式也不应该加载applicationContext.xml
-----java类方式---------------
public class springTestListen implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext Context) throws ServletException {
// AnnotationConfigWebApplicationContext app = new AnnotationConfigWebApplicationContext();
// app.register(configs.class);
// app.setServletContext(Context);
Context.addListener(new ContextLoaderListener());
Context.addListener(new WebAppRootListener());
// Context.setInitParameter("contextConfigLocation", "classpath:**/*Context.xml");
Context.setInitParameter("contextClass", "org.springframework.web.context.support.AnnotationConfigWebApplicationContext");
Context.setInitParameter("contextConfigLocation","spring.config.configs");
}
}
------------web.xml(二选一)
ntext-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>spring.config.configs</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
springMvc
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9e3wV1VX-1661235847069)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220719093026744.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhi5RrqR-1661235847069)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220725133119911.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A83Yf1Rv-1661235847069)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20220726170930816.png)]
springMvc常用注解
注解 | |
---|---|
@RequestMapping | 作用:用于建立请求URL和处理请求方法之间的对应关系位置, 1.类上,请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录; 2.方法上,请求URL的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径属性; 3.value:用于指定请求的URL。它和path属性的作用是一样的method:用于指定请求的方式 4.params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样例如: |
@RequestBody | @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的),所以只能发送POST请求。 GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。 在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。 |
-
springMvc.xml其他配置
-
在spring-webmvc的jar包下面有一个DispatcherServlet.properties配置着默认的DispatcherServlet需要的组件如视图解析器,适配器等等
web.xml方式配置dispatcher <servlet> <servlet-name>Diaspacter</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:*mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Diaspacter</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
1
前端控制器 DispatcherServlet-
静态资源的处理
浏览器的请求到达Tomcat的时候发现有一个servlet为dispatcherServlet,会拦截所有请求,转到普通的controller,这时候要访问静态资源就应该配置
< m v c : r e s o u r c e m a p p i n g = " / j s / ∗ ∗ " l o c a t i o n = " / j s / " / > 或者 < m v c : d e f a u l t − s e r v l e t − h a n d l e r / > <mvc:resource mapping="/js/**" location="/js/" /> 或者 <mvc:default-servlet-handler /> <mvc:resourcemapping="/js/∗∗"location="/js/"/>或者<mvc:default−servlet−handler/>
2
处理器映射器 HandlerMapping3
处理器适配器 HandlerAdapter4
处理器 Handler5
视图解析器 View Resolver6
视图 View-
数据响应:
-
1.直接返回字符串
-
2.返回ModelAndView对象
@RequestMapping("/b") public ModelAndView run1(/**或者将Mv模型视图加入参数,容器会根据参数自动注入*/){ ModelAndView MV = new ModelAndView(); //将数据添加到模型的域中 MV.addObject("shujv","niaho"); //设置视图名称 MV.setViewName("success.jsp"); return MV; }
-
回写数据
-
1.原生回写数据
@RequestMapping("/d") public void run2(HttpServletResponse resp) throws IOException { resp.setCharacterEncoding("GBK"); resp.getWriter().print("原生回写数据"); }
-
2.加注解ResponseBody告知框架,方法返回的字符串不是跳转而是直接在http响应体中返回
-
3.返回对象或者集合,配置处理器适配器告知转化为json
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean> </list> </property> </bean>
-
-
获取请求参数
普通类型的请求参数
@RequestMapping("/d")
@ResponseBody
public void run2(String username,String age) throws IOException {
System.out.println(username);
System.out.println(age);
}
-----------------------
@RequestParam
如果前端的参数的名字 name想要绑定到username上,
public void run2(@RequestParam(value="name" require=false默认为true)String username,String age) throws IOException
获取POJO类型的参数
//---实体类
public class userBean {
private String username;
private String password;
}
http://localhost:8080/find?username=zhangfeng&age=11
@RequestMapping("/d")
@ResponseBody
public void run2(userBean user) throws IOException {
System.out.println(user);
}
获得数组类型的参数
http://localhost:8088/list?string=a&string=2&string=t
@RequestMapping("/list")
@ResponseBody
public void run3(String[] string) {
System.out.println(Arrays.asList(string));
}
获取集合类型的参数
涉及到json需要自己导包,再配置处理适配器
1.了解
封装为VO对象,集合作为VO类的一个属性
2.当使用Ajax提交的时候,可以指定contentType为json形式,在方法参数的位置使用@RequestBody可以直接接受集合数据而无需使用POJO包装
@RequestMapping("/list")
@ResponseBody
public void run4(@RequestBody List<userBean> user) {
System.out.println(user);
}
//请求参数
[
{
"username": "xxx",
"password": "14"
},
{
"username": "xxx2",
"password": "15"
}
]
不管是接受json还是发送json都需要自己配置导包
拦截器
步骤
-
自定义拦截器类实现HandlerInterceptor接口
//在目标执行之前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return false; } //该方法是在当前请求进行处理之后被调用,前提是preHandle方法的返回值为true 时才能被调用,且它会在DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } //在流程执行完毕之后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
-
配置
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*"/> <bean class="web.interCeptor.myInterceptor(自定义的拦截器的全类名)"></bean> </mvc:interceptor> </mvc:interceptors>