Java 45:Spring

好久没有回来了,今天回来

书接上回


Spring 


Spring 是一个开源的,轻量级的 用来简化应用开发的框架

简化开发

对常用的apt 做了封装和简化

管理对象

spring 提供一个容器,帮我们创建对象以及建立对象之间的依赖关系

集成其他框架

Spring 可以将其他的一些框架集成进来 比如 集成用于:

任务调度 Quartz

spring 容器

spring 容器是 spring 框架中的一个核心模块 用于管理对象

启动spring 容器

1、导包 

spring-webmvc

2、添加配置文件

applicationContext.xml

3、启动spring容器

ApplicationContext=》接口

ClassPathXmlApplicationContext=》实现类

//接口                  // 实现类                           //spring的配置二文件

ApplicationContext ac = new ClassPathXmlApplicationContext("annotation.xml");


如何创建对象

使用容器创建对象=》 反射

方式1、利用无参构造器

1、给类添加无参构造器(或者默认构造器)

2、使用元素在applicationContext.xml



3、调用容器的getBean方法来获取对象

Student sut = (Student)ac.getBean("stu1");
Student sut = ac.getBean("stu1",Student.class);

Date d = ac.getBean("date",Date.class);
System.out.println(d.toString());


方式2、 使用静态工厂方法

通过调用类的静态方法来创建对象

1、


2、

Calendar cal1 = ac.getBean("cal1",Calendar.class);
System.out.println(cal1);


方式3、使用实例工厂方法

通过调用对象的实例方法来创建对象

1、

2、

Date time1 = ac.getBean("time1",Date.class);
System.out.println(time1);

作用域


ApplicationContext ac = new ClassPathXmlApplicationContext("scope.xml");
ScopeBean s1 = ac.getBean("s1",ScopeBean.class);
ScopeBean s2 = ac.getBean("s1",ScopeBean.class);
System.out.println(s1 == s2); flase


生命周期

初始化 

分配资源

销毁 

释放资源

public class MessageBean {
public MessageBean() {
System.out.println("MessageBean()");
}
public void init() {
System.out.println("init()");
}
public void sendMsg() {
System.out.println("sendMsg()");
}
public void destroy() {
System.out.println("destroy()");
}
}


AbstractApplicationContext 接口 是ApplicationContext 的子接口

AbstractApplicationContext 中才有关闭方法

ac.close();

@Test
public void test2() {
AbstractApplicationContext ac = new ClassPathXmlApplicationContext("scope.xml");
MessageBean mb1 = ac.getBean("mb1",MessageBean.class);
mb1.sendMsg();
ac.close();
}


延迟加载


spring 容器启动后,会检查xml文件 会将所有作用域为单例的bean 创建好


IOC  控制反转

Inversion Of Controll

是指的 对象之间的依赖关系是由容器来建立

DI 依赖注入

Dependency Injection 

容器通过调用对象提供的set

方法或者构造器来建立依赖关系

IOC 是目标 DI是手段

类实现接口  用接口



package ioc;
public class B {
public B() {
System.out.println("B");
}
public void f1() {
System.out.println("B-f1()");
}
}
package ioc;
public class A {
private B b;
private C c;
public A() {
System.out.println("A");
}
public void execute() {
System.out.println("execute");
b.f1();
c.f1();
}
public void setB(B b) {
System.out.println("setB()");
this.b = b;
}
public void setC(C c) {
System.out.println("setc()");
this.c=c;
}
}
package ioc;
public class C {
public C() {
System.out.println("C");
}
public void f1() {
System.out.println("C-f1()");
}
}
 

 
 
 
 
@Test
public void test5() {
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
A a = ac.getBean("a1",A.class);
a.execute();
}


set方式注入

1、提供相应的set方法

2、配置

3、

package ioc;
public class B implements IB{
public B() {
System.out.println("B");
}
public void f1() {
System.out.println("B-f1()");
}
}
package ioc;
public class A {
private IB b;
public A() {
System.out.println("A");
}
public void execute() {
System.out.println("execute");
b.f1();
}
public void setB(IB b) {
System.out.println("setB()");
this.b = b;
}
}
package ioc;
public class C implements IB{
public C() {
System.out.println("C");
}
public void f1() {
System.out.println("C-f1()");
}
}
package ioc;
public interface IB {
public void f1();
}
 

 
 
 
@Test
public void test5() {
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc.xml");
A a = ac.getBean("a1",A.class);
a.execute();
}


 
 

name 就是 setB    单词首字母大写 加set 

ref 就是bean 的id

 

这个使用了接口

接口IB   有一个方法  f1()

两个 B 和 C 类  实现了 IB 接口

在A类中使用了IB接口  那么 B 类 和C 类都可以传入 IB 接口中  

那么就实现了  代码不变 在xml中变 property 的 ref 值  也就是  注入的 bean ID 就可以  .就可以换实现方式了.

构造器方式注入(很少使用)

1、添加相应的构造器

2、配置constructor-arg 元素



public class B {
public B() {
System.out.println("B");
}
public void f1() {
System.out.println("B-f1");
}
}
public class A {
private B b;
public A() {
System.out.println("A");
}
public A(B b) {
System.out.println("A->B");
this.b=b;
}
public void execute() {
System.out.println("A-execute");
b.f1();
}
}
@Test
public void test7(){
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc2.xml");
A a1 = ac.getBean("a",A.class);
a1.execute();
}


自动装配(自动注入)

自动装配是指的spring 容器依据某种规则 自动建立对象之间的依赖关系

默认情况下 容器不会自动装配

可以通过指定 autowire属性来 告诉容器进行自动装配 容器仍然需要通过调用set 方法和构造器来完成依赖关系的建立

 

 

 


优先使用 byName

package ioc;
public class Waiter {
public Waiter() {
System.out.println("Waiter()");
}  
}
package ioc;
public class Restaurant {
private Waiter wt;
public void setWt(Waiter wt) {
this.wt = wt;
}
public Restaurant() {
System.out.println("Restaurant()");
}
@Override
public String toString() {
return "Restaurant [wt=" + wt + "]";
}
}

   
  
  


private Waiter wt;   属性名为wt 那 autowire byName 就会在 xml配置文件中找一个 bean id 为 wt 的 类用 set 方式注入

若没有找到就注入 null


注入基本类型的值  注入类的时候用 ref  注入基本类型用value

value 




package value;
public class ValueBean {
private String name;
private int age;
public ValueBean() {
System.out.println("ValueBean()");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "ValueBean [name=" + name + ", age=" + age + "]";
}
}
@Test
public void test9() {
ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
ValueBean vb = ac.getBean("vb1",ValueBean.class);
System.out.println(vb.toString());
}


注入集合类型的值

sprint 支持 List Set Map Properties

 

List






北京
上海
广州



Set






北京
上海
广州











Map

 




北京
上海
广州
















Properties






北京
上海
广州


















root
1234



package value;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class ValueBean {
private String name;
private int age;
private List city;
private Set interest;
private Map score; 
private Properties db;
public ValueBean() {
System.out.println("ValueBean()");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setCity(List city) {
this.city = city;
}
public void setInterest(Set interest) {
this.interest = interest;
}
public void setScore(Map score) {
this.score = score;
}
public void setDb(Properties db) {
this.db = db;
}
@Override
public String toString() {
return "ValueBean [name=" + name + ", age=" + age + ", city=" + city + ", interest=" + interest + ", score="
+ score + ", db=" + db + "]";
}
}

@Test
public void test9() {
ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
ValueBean vb = ac.getBean("vb1",ValueBean.class);
System.out.println(vb.toString());
}

集合类型的值配置成一个bean 方便 复用

但是要引用 util 标签

xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation 中添加:
   http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util-2.0.xsd


北京
上海
广州












root
123456








package value;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class ValueBean {
private String name;
private int age;
private List city;
private Set interest;
private Map score; 
private Properties db;
public ValueBean() {
System.out.println("ValueBean()");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setCity(List city) {
this.city = city;
}
public void setInterest(Set interest) {
this.interest = interest;
}
public void setScore(Map score) {
this.score = score;
}
public void setDb(Properties db) {
this.db = db;
}
@Override
public String toString() {
return "ValueBean [name=" + name + ", age=" + age + ", city=" + city + ", interest=" + interest + ", score="
+ score + ", db=" + db + "]";
}
}

@Test
public void test10() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");
    ValueBean vb = ac.getBean("vb2",ValueBean.class);
    System.out.println(vb.toString());
}

spring 读取properties 文件的配置

src/main/resources/config.properties=>>pagesize=10

@Test

public void test11() {

ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");

System.out.println(ac.getBean("config"));

}

使用spring 表达式

#{bean的id.属性名(要有get方法)}

#{msg.name}  ==》读取基本类型

#{msg.interest[0]} ==> 读取list(不能读set  set没有下标)

#{msg.score.english} =>读取map 如果是用的中文做map的key ==>#{msg.score['英语']}

#{config.pagesize}=>读取

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" 

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       ">


北京

上海

广州




root

1234

北京

上海

广州

root

123456

package value;


public class SpelBean {

private String name;

private String city;

private double score;

private String pageSize;

public SpelBean() {

System.out.println("SpelBean()");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getCity() {

return city;

}

public void setCity(String city) {

this.city = city;

}

public double getScore() {

return score;

}

public void setScore(double score) {

this.score = score;

}

public String getPageSize() {

return pageSize;

}

public void setPageSize(String pageSize) {

this.pageSize = pageSize;

}

@Override

public String toString() {

return "SpelBean [name=" + name + ", city=" + city + ", score=" + score + ", pageSize=" + pageSize + "]";

}


}

Properties文件:

pagesize=10


@Test

public void test12() {

ApplicationContext ac = new ClassPathXmlApplicationContext("value.xml");

SpelBean sp = ac.getBean("sp1",SpelBean.class);

System.out.println(sp);

}

SpelBean [name=张三, city=上海, score=60.0, pageSize=10]

使用注解简化配置

组件扫描

spring 容器会扫描该包及其子包下面的所有类 

如果类前面有特定的注解@Component 

则 spring 容器会将其纳入容器进行管理(相当于在配置文件中,配置了一个bean元素)

注解的类型:

@Component  通用注解

@Named 通用注解

@Repository持久层组件注解

@Service业务组件注解

@Controller 控制层注解

@Scope("prototype") => 指定作用域  原型

@Scope("singleton") =>单例

@PostConstruct =》 指定初始化方法(放在方法的上面)  需要 导包(在tomcat中有)javax.annotation.PostConstruct;

@PreDestroy =》 指定销毁方法(放在方法的上面)  需要导包javax.annotation.PreDestroy;

@Lazy(true) =》 延迟加载

指定依赖注入关系

@Autowired 

@Qualifier

处理构造器注入和Setter注入

当采用set 方式注入时,可以将@Autowired 添加到set 方法前面,

如果不使用@Qualifier则容器会使用byType 的方式来注入 有可能出错,

所以建议使用@Qualifier注解 明确指定要注入的bean的id

public class Resturant {

private Waiter wt;

@Autowired

public void setWt(@Qualifier("wt") Waiter wt) {

System.out.println("setWt()");

this.wt = wt;

}

}

还可以写在属性前面  这样set方法都不用写了,通过反射来完成的

@Autowired

@Qualifier("wt")

private Waiter wt;

当采用构造器注入时,可以将该注解添加到对应的构造器前面即可

@Inject

@Named

和@Autowired用一样,需要导包,用法和@Autowired @Qualifier一样是 是sun 公司开发的

@Resource

需要导包 javax  tomcat 中有

只能处理Setter 但是大部分都是用Setter 注入

Setter 使用@Resource

添加到set方法前面,使用name属性指定要注入的bean 的id   (如果不指定,会按照byType的方法注入)

也可以将该注解添加到属性前面

构造器使用@Autowired

package ioc;


import javax.annotation.Resource;


public class Bar {

private Waiter wt;


public Bar() {

System.out.println("Bar()");

}


public Waiter getWt() {

return wt;

}

@Resource(name = "wt")

public void setWt(Waiter wt) {

this.wt = wt;

}


@Override

public String toString() {

return "Bar [wt=" + wt + "]";

}


}

步骤 

1、在类中添加注解

@Component  bean的id缺省值 是类名首字母小写之后的名字

@Component(sb1) bean 的id 为 sb1

2、在配置文件中,添加组件扫描的配置

java 类中添加注解

xml 中

     

       

      

import org.springframework.stereotype.Component;


@Component("sb1")

public class SomeBean {


public SomeBean() {

System.out.println("SomeBean()");

}

}


@Value 注解的类型: 

可以使用该注解来注入基本类型的值

可以使用该注解来使用spring 表达式

该注解可以添加到属性前或者添加到对象的set 方法前

package ann;


import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;


@Component("mg")

public class Manager {

@Value("#{config.pageSize}")

private String pageSize;

@Value("李四")

private String name;

public Manager() {

System.out.println("Manager()");

}

@Override

public String toString() {

return "Manager [pageSize=" + pageSize + ", name=" + name + "]";

}

}


config.properties

pageSize=10

annotation.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd">

 

 

 

@Test

@Test

public void test02() {

ApplicationContext ac  = new ClassPathXmlApplicationContext("annotation.xml");

Manager mg = ac.getBean("mg",Manager.class);

System.out.println(mg);

}

Srping MVC

是一个mvc 框架,用来简化基于mvc 架构的web 应用开发

五大组件

DispatcherServlet==》前端控制器

接受请求,依据HandlerMapping 的配置调用相应的模型来处理 spring mvc 提供的需要配置

HandlerMapping

DispatcherServlet的秘书  包含了请求路径与模型的对关系 spring mvc 提供的需要配置

Controller   处理器  自己写

负责处理业务逻辑

ModelAndView

封装了处理结果   处理结果除了数据之外,还可能有视图名

ViewResolver  视图解析器  spring mvc 提供的需要配置

DispatcherServlet依据ViewResolver的解析

调用真正的视图对象来生产相应的页面

DispatcherServlet的秘书

jsp

freemarker

velocity

五大组件的关系

DispatcherServlet 收到请求之后 依据HandlerMapping 的配置 调用相应的Controller来处理

Controller将处理结果封装成ModelAndView对象然后返回给DispatcherServlet 

DispatcherServlet 依据ViewResolver的解析调用相应的视图对象(比如某个jsp)来生产相应的页面

ModelAndView 有两个构造器

1、ModelAndView(String viewName)

viewName 是视图名

2、ModelAndView(String viewName,Map data)

viewName 是视图名

data 用于封装处理结果数据

1、导包

2、添加spring配置文件

3、配置DispatcherServlet

4、写Controller

5、写jsp

6、在spring 配置文件中,添加配置 HandlerMapping、Controller、ViewResolver

1、导包 spring-webmvc

2、添加springmvc.xml spring 配置文件

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       ">

3、

springmvc

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath:springmvc.xml

1

  

springmvc

*.do


4、

package controller;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.mvc.Controller;


public class HelloController implements Controller{


public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

System.out.println("handlerequest");

return new ModelAndView("hello");

}


}

5、

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

SteveZong

Hello Spring MVC

6、

helloController


使用注解来开发基于springmvc的web应用

1、导包

2、添加spring 配置文件

3、配置 DispatcherServlet

4、写Controller

5、写jsp

6、在spring配置文件中,添加

a、组件扫描

b、mvc注解扫描

c、视图解析器



1、导包 spring-webmvc


2、添加springmvc.xml spring 配置文件

DispatcherServlet在初始化方法里面会读取该初始化参数的值来获取spring 配置文件的位置然后启动spring容器

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" 

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       http://www.springframework.org/schema/mvc

       http://www.springframework.org/schema/mvc/spring-mvc.xsd

       ">


3、

 springmvc

 org.springframework.web.servlet.DispatcherServlet

 

  contextConfigLocation

  classpath:spring-webmvc.xml

 

 1

  

  springmvc

  *.do

  

4、

package springmvc002;


import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;


/**

 *不用实现Controller接口 

 *可以在处理器类当中,添加多个方法

 *每一个方法处理一种类型的请求

 *方法名 不做要求,返回类型可以是ModelAndView 也可以是String

 *@Controller 将该处理器纳入容器进行管理(spring 配置文件中不用再配置该处理器了)

 *使用 @RequestMapping 告诉前端控制器DispatcherServlet 请求路径与处理器的方法的对应关系 (spring 配置文件不用配置HandlerMapping)

 */

//  http://ip:port/springmvc002/hello.do

@Controller

public class HelloController {

@RequestMapping("/hello.do")

public String hello() {

return "hello";

}

}



//+++++++++++++++++++++++++++++++++++++++

//http://ip:port/springmvc002/demo/hello.do

@Controller

@RequestMapping("/demo")

public class HelloController {

@RequestMapping("/hello.do")

public String hello() {

return "hello";

}

}

//+++++++++++++++++++++++++++++++++++++++


5

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

    pageEncoding="ISO-8859-1"%>

Insert title here

Hello,SpringMVC


6、

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:tx="http://www.springframework.org/schema/tx" 

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xsi:schemaLocation="

       http://www.springframework.org/schema/beans 

       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

       http://www.springframework.org/schema/tx 

       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

       http://www.springframework.org/schema/context

       http://www.springframework.org/schema/context/spring-context-3.0.xsd

       http://www.springframework.org/schema/aop

       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

       http://www.springframework.org/schema/util

       http://www.springframework.org/schema/util/spring-util-2.0.xsd

       http://www.springframework.org/schema/mvc

       http://www.springframework.org/schema/mvc/spring-mvc.xsd

       ">

 

读取请求参数值

通过request对象将request 对象作为方法的入参即可

@RequestMapping("login.do")

//通过request对象 读取请求参数值

public String login(HttpServletRequest  request) {

String adminCode = request.getParameter("adminCode");

System.out.println(adminCode);

return "index";

}

@RequestMapping("login2.do")

//使用 注解 @RequestParam

//参数名和 jsp中的name 一样 可以不用注解(java 反射可能不能拿到形参) 但是最好还是要添加

//参数名和 jsp中name 不一样,需要用注解

//用法,将注解添加到形参的前面

public String login2(String adminCode, @RequestParam("password")String pw) {

System.out.println(adminCode);

System.out.println(pw);

return "index";

}

使用javabean 封装请求参数值

先写一个java bean

在形参的地方放 javaBean

javaBean 的属性名和 请求参数名一致,并且提供set get 方法

package springmvc002;

import java.io.Serializable;

public class AdminParam  implements Serializable{

private String adminCode;

private String password;

public String getAdminCode() {

return adminCode;

}

public void setAdminCode(String adminCode) {

this.adminCode = adminCode;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

}


@RequestMapping("login3.do")

//将请求参数封装成一个javabean

public String login3(AdminParam ap) {

System.out.println(ap.getAdminCode());

System.out.println(ap.getPassword());

return "index";

}

向页面传值  优先使用生命周期短的

使用reqeust

@RequestMapping("login4.do")

//使用request 将数据绑定到request 上 然后转发到某个jsp     springmvc默认使用转发

public String login4(AdminParam ap,HttpServletRequest request) {

System.out.println("login4()");

String adminCode = ap.getAdminCode();

System.out.println(adminCode);

//将数据绑定到request

request.setAttribute("adminCode", adminCode);

//springmvc 默认使用转发

return "index";

}

使用 ModelAndView 将数据 先封装到ModelAndView 对象里面,然后将该对象作为方法的返回值

@RequestMapping("login5.do")

//使用ModelAndView

public ModelAndView login5(AdminParam ap) {

String adminCode = ap.getAdminCode();

System.out.println(adminCode);

//构造ModelAndView对象

Map data = new HashMap();

//相当于request.setAttribute("adminCode",adminCode);

// 所以key 相当于 

data.put("adminCode",adminCode);

ModelAndView  mav = new ModelAndView("index",data);

return mav;

}

使用ModelMap 将这个对象 作为方法的参数,然后将数据绑定到该对象

@RequestMapping("login6.do")

public String login6(AdminParam ap , ModelMap mm) {

String adminCode = ap.getAdminCode();

System.out.println(adminCode);

//相当于request.setAttribute("adminCode",adminCode);

mm.addAttribute("adminCode", adminCode);

return "index";

}

使用session 将数据绑定到session中 session 作为方法的参数  直接使用 session 前端控制器会分析请求

@RequestMapping("login7.do")

public String login7(AdminParam ap, HttpSession session) {

String adminCode = ap.getAdminCode();

session.setAttribute("adminCode", adminCode);

return "index";

}

重定向 

302

如果方法的返回值是String 

在重定向地址前添加"redirect:"

return "redirect:toIndex.do";

@RequestMapping("login8.do")

public String login8() {

System.out.println("login8()");

return "redirect:toIndex.do";

}

@RequestMapping("toIndex.do")

public String toIndex() {

System.out.println("toIndex.do");

return "index";

}

如果方法的返回值是ModelAndView

@RequestMapping("login9.do")

public ModelAndView login9() {

System.out.println("login9()");

RedirectView rv = new RedirectView("toIndex.do");

return new  ModelAndView(rv);

}

反射

是JAVA API 是Java 提供的现成的类

是Java 提供的动态执行机制 动态加载类,动态创建对象 动态访问实现,动态条用方法

静态与动态

静态:事先约定的规则 执行期间按照固定规则执行

动态:事先没有约定,在执行期间动态确定执行规则

JAVA 中的静态执行:编译或已经就确定执行规则(执行次序) 在运行期间按照变异结果顺序执行

JAVA 中的动态执行:运行期间才能确定加载哪些类,创建哪些对象,执行哪些方法

动态加载类

Java 提供了动态加载类的API

Class cls = Class.forName(类名);

System.out.println(cls);

动态创建对象

语法

Object obj = cls.newInstance();

System.out.println(obj);

cls.newInstance();

习性cls引用的类信息中的无参构造器,动态创建实例,如果类没有无参构造器,抛出异常

反射可以调用有参构造器

动态获取类的方法信息

//动态获取类的方法信息,从 cls 带来的类信息中获取全部的方法信息

Method[] ary = cls.getDeclaredMethods();

for(Method method:ary) {

System.out.println(method);

}

method 是从类中获取的

method.invoke(执行方法的对象,传递的参数)

method.invoke(对象,参数1,参数2,参数3...)

必须在对象上执行一个非静态方法,调用方法适合必须有对象

在invoke方法执行适合必须传递包含当前方法的对象

Class cls = Class.forName(className);

//Object obj = cls.newInstance();

Method[] methods = cls.getMethods();

Object obj = cls.newInstance();

for(Method sub:methods) {

if(sub.getName().startsWith("test")) {

System.out.println(sub.getName());

sub.invoke(obj);

sub.invoke(obj,arg[1],arg[~],arg[n]);

}

}

invoke 方法有返回值,返回被调用方法执行的结果,对象后面参数是执行方法适合传递的参数

*** invoke 可以调用私有方法


//动态加载类

Scanner in = new Scanner(System.in);

String className = in.nextLine();

Class cls = Class.forName(className);

//找到demo方法

//Class提供了根据方法签名找到指定方法信息的API

String name="demo";

//类型列表 Class[]

//String.class 字符串类型

//int.class int类型

//根据方法签名在cls查找方法信息

Class[] types = {String.class,int.class};

Method method = cls.getDeclaredMethod(name, types);

System.out.println(method.getName());

//执行私有方法

//打开方法执行权限,违反封装

method.setAccessible(true);

Object obj  = cls.newInstance();

method.invoke(obj, "tom",22);

System.out.println(obj);

反射用途

eclipse 中解析类的结构使用了反射

Junit识别被测试方法

Spring 管理Bean对象 注入Bean属性

注解的解析

强行执行私有方法 访问私有属性

MVC

系统分层

  UI  BLL     DAL

表示层业务层持久层

表示层:数据展现和控制逻辑 (请求分发)

业务层:业务逻辑的处理

持久层:数据库访问

v c合并:

表示层:数据展现和控制逻辑 (请求分发)

m分两层:

业务层:业务逻辑的处理

持久层:数据库访问

表示层 调用 业务层 调用  持久层

  (接口)(接口)

上一层通过接口调用下一层提供的服务

比如 

业务层调用持久层提供的接口

下一层发生改变 不影响上一层

方便代码的维护

junit

@Before

修饰的方法会在测试方法运行之前执行

可以把启动容器的方法 写在这个里面

然后在类中添加一个属性ApplicationContext

DataSource

连接池的接口

dbcp c3p0 都支持

中文乱码解决方法

在web.xml  中 添加一个filter 过滤器

然后用spring  提供好的一个类org.springframework.web.filter.CharacterEncodingFilter

配置一下就可以了

spring-web-3.2.8.RELEASE.jar

包中

pageEncoding

org.springframework.web.filter.CharacterEncodingFilter

encoding

UTF-8

pageEncoding

/*

为何会有乱码

表单提交时,浏览器会对钟文杰进行编码   (会只用打开表示所在页面时的字符集来编码 比如utf-8)

但是服务器默认使用iso-8859-1来解码 所以就会有乱码

springmvc 提供了一个过滤器 CharacterEncodingFilter  表单提交要采用post方法提交

客户端的编码与过滤器的编码要一样

spring 拦截器

spring 提供的一个特殊的组件 当DispatcherServlet 收到请求之后,如果有拦截器,会先调用拦截器,然后调用相应的处理器Controller

过滤器  属于Servlet规范

拦截器属于spring框架

可以配置多个

1、写一个java 类 实现HandlerInterceptor接口

2、实现具体的拦截处理逻辑,比如 session验证,日志记录,权限管理

3、配置拦截器

1、写java类

package interceptors;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;


public class SomeInterceptor implements HandlerInterceptor{

/**

* 进入controller

* DispatcherServlet 收到请求之后 会先调用preHandle  方法, 如何方法返回true 通过 继续向后调用,false 不再向后调用

* arg2 描述处理器方法的一个对象  一般都用不到

*/

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

System.out.println("preHandle");

return true;

}

/**

* 处理器ontroller的方法已经 处理完 正要 返回ModelAdnView对象给DispatcherServlet 执行postHandle 可以在在这个方法里面修改处理结果

*/

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

System.out.println("postHandle");

}

/**

* 最后执行的方法 只有当preHandle 方法返回值为true时,该方法才会执行

* ex是处理器梭抛出的异常,可以写一个拦截器用来处理这些异常

*/

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

throws Exception {

System.out.println("afterCompletion");

}


}


3、

Spring MVC 处理异常方式有三种

1使用SpringMVC提供的简单异常处理器

SimpleMappingExceptionResolver

异常毅力页面获取异常对象名exception 适合全局处理简单异常

error

2实现HandlerExceptionResolver接口

自定义异常处理器

3使用@ExceptionHandler注解实现异常处理

1、在处理器类当中,添加一个异常处理方法 该方法必须使用@ExceptionHandler修饰

2、在该方法里面依据异常类型,分别进行不同的处理

3、添加异常处理页面

//一个异常处理方法

//ex 是其他方法所抛出的异常

@ExceptionHandler

public String exHandle(HttpServletRequest request,Exception ex) {

System.out.println("exHadnle()");

//依据异常类型的不同,分别进行 相应的处理

if(ex instanceof NumberFormatException) {

request.setAttribute("error", "亲,请输入正确的数字");

}else if(ex instanceof StringIndexOutOfBoundsException) {

request.setAttribute("error", "数组下标越界");

}else {

request.setAttribute("error", "系统异常,请稍后重试");

}

return "error";

}

Spring JDBC


spring 对jdbc的封装,使用springjdbc 访问数据库可以不用写一写重复性的代码,比如获取连接 关闭连接等

使用

1、导包

spring-webmvc 3.2.8

spring-jdbc   3.2.8

mysql-connector 5.1.44

dbcp 1.4

2、添加spring 配置文件

3、配置JdbcTemplate

JdbcTemplate 提供了一些方法,  来访问数据库

4调用JdbcTemplate 提供的方法来访问数据库

通过将JdbcTemplate注入到DAO。

JdbcTempate

1、导包

2、添加spirng 配置文件


zongxuan

zongxuan

jdbc:mysql://172.29.12.158:3306/test?useUnicode=true&characterEncoding=utf8

com.mysql.jdbc.Driver

10

500


destroy-method="close">

3、配置JdbcTemplate



4(插入)

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.stereotype.Repository;


import entity.Emp;


@Repository("empDAO")

public class EmpDAOImpl  implements EmpDAO{


@Resource(name="jt")

private JdbcTemplate template;

public void save(Emp emp) {

//sql   然后使用 Object 数组赋值. 调用 update方法

String sql = "INSERT INTO emp2 (name,age) VALUES (?,?)";

Object[] params = new Object[] {emp.getName(),emp.getAge()};

template.update(sql,params);

}

}

4、(查询)

package dao;


import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;


import javax.annotation.Resource;


import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.stereotype.Repository;


import entity.Emp;


@Repository("empDAO")

public class EmpDAOImpl  implements EmpDAO{


@Resource(name="jt")

private JdbcTemplate template;

public void save(Emp emp) {

String sql = "INSERT INTO emp2 (name,age) VALUES (?,?)";

Object[] params = new Object[] {emp.getName(),emp.getAge()};

template.update(sql,params);

}


public List findAll() {

List emps = new ArrayList();

String sql = "SELECT * FROM emp2";

emps = template.query(sql, new EmpRowMapper());

return emps;

}

//告诉JdbcTemplate 如何将ResultSet 中的一条记录转换成对应的Entity对象

class EmpRowMapper implements RowMapper{

//rs 要处理的结果集, index 当前正在处理的记录的下标

public Emp mapRow(ResultSet rs, int index) throws SQLException {

Emp emp = new Emp();

emp.setId(rs.getInt("id"));

emp.setName(rs.getString("name"));

emp.setAge(rs.getDouble("age"));

return emp;

}

}


}

4(查询 By 条件)

package dao;


import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;


import javax.annotation.Resource;


import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.stereotype.Repository;


import entity.Emp;


@Repository("empDAO")

public class EmpDAOImpl  implements EmpDAO{


@Resource(name="jt")

private JdbcTemplate template;

public void save(Emp emp) {

String sql = "INSERT INTO emp2 (name,age) VALUES (?,?)";

Object[] params = new Object[] {emp.getName(),emp.getAge()};

template.update(sql,params);

}


public List findAll() {

List emps = new ArrayList();

String sql = "SELECT * FROM emp2";

emps = template.query(sql, new EmpRowMapper());

return emps;

}

//告诉JdbcTemplate 如何将ResultSet 中的一条记录转换成对应的Entity对象

class EmpRowMapper implements RowMapper{

//rs 要处理的结果集, index 当前正在处理的记录的下标

public Emp mapRow(ResultSet rs, int index) throws SQLException {

Emp emp = new Emp();

emp.setId(rs.getInt("id"));

emp.setName(rs.getString("name"));

emp.setAge(rs.getDouble("age"));

return emp;

}

}


public Emp findById(int id) {

Emp emp = null;

String sql = "SELECT * FROM emp2 WHERE id=?";

Object[] args = new Object[] {id};

emp  = template.queryForObject(sql, args,new EmpRowMapper());

return emp;

}


}


你可能感兴趣的:(Java 45:Spring)