Spring

注解注入

注解注入属性:

  1. @Autoware 和 @Resource 功能一样
  2. 注解采用默认规则自动注入
    1. 先按照 名字规则,自动注入
    2. 如果名字不匹配,就按照类型自动注入
  3. 注解可以标注在 Bean属性 和 实例变量上
  4. 注解必须经过Spring的解析出来才能生效。

原理:

@Autoware

@Autoware 用于标注被注入的Bean属性或者实例变量。 Spring运行期间会自动按照名字相同或者类型相同的规则进行注入。

  1. 编写Tool接口:

    public interface Tool {
    
    }
    
  2. 编写类

    @Component("tool") 
    public class Axe implements Serializable, Tool {
    
        @Override
        public String toString() {
            return "斧子";
        }
    }
    
  3. 编写类

    @Component
    public class Worker {
        @Autowired
        private Tool tool;
    
        public Worker() {
            name="光头强";
        }
    
        public void work() {
            System.out.println(name+"使用"+tool+"砍树"); 
        }
    }
    
  4. 配置组件扫描

    <!-- 配置Spring的注解扫描功能-->
    <context:component-scan base-package="day03"/>
    
  5. 测试:

    public class TestCase {
        ClassPathXmlApplicationContext ctx;
    
        @Before
        public void init() {
            ctx = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");
        }
    
        @After
        public void destroy() {
            ctx.close();
        }
    
        @Test
        public void testWorker() {
            //Spring:解析注解,控制对象,注入属性,属性不是空
            Worker worker = ctx.getBean("worker",
                    Worker.class);
            worker.work();
            //脱离Spring容器自己创建对象,无人解析属性,
            //无人注入属性,属性为空
            Worker worker2 = new Worker();
            worker2.work();
        }
    }
    

@Resource

Resource是Java提供的注解,其功能与Autowared基本一样:

  1. 编写Tool接口:

    public interface Tool {
    
    }
    
  2. 编写类

    @Component("tool") 
    public class Axe implements Serializable, Tool {
    
        @Override
        public String toString() {
            return "斧子";
        }
    }
    
  3. 编写类

    @Component
    public class Worker {
        @Resource
        private Tool tool;
    
        public Worker() {
            name="光头强";
        }
    
        public void work() {
            System.out.println(name+"使用"+tool+"砍树"); 
        }
    }
    
  4. 配置组件扫描

    <!-- 配置Spring的注解扫描功能-->
    <context:component-scan base-package="day03"/>
    
  5. 测试:

    public class TestCase {
        ClassPathXmlApplicationContext ctx;
    
        @Before
        public void init() {
            ctx = new ClassPathXmlApplicationContext(
                    "applicationContext.xml");
        }
    
        @After
        public void destroy() {
            ctx.close();
        }
    
        @Test
        public void testWorker() {
            //Spring:解析注解,控制对象,注入属性,属性不是空
            Worker worker = ctx.getBean("worker",
                    Worker.class);
            worker.work();
            //脱离Spring容器自己创建对象,无人解析属性,
            //无人注入属性,属性为空
            Worker worker2 = new Worker();
            worker2.work();
        }
    }
    

标注Bean属性

@Autowared 和 @Resource 注解不仅仅能够标注实例变量,还能标注Bean属性方法,实现Bean属性注入。

  1. 编写衣服类

    @Component
    public class Clothes {
    
        @Override
        public String toString() {
            return "工作服";
        }
    }
    
  2. 重构Worker

    @Component
    public class Worker {
        @Autowired
        private Tool tool;
    
        //Clothes 衣服
        private Clothes clothes;
    
        public Worker() {
            name="光头强";
        }
    
        @Autowired
        public void setClothes(Clothes clothes) {
            this.clothes = clothes;
            System.out.println("setClothes()"+clothes);
        }
    
        public Clothes getClothes() {
            return clothes;
        }
    
    
        public void work() {
            System.out.println(name+"使用"+tool+"砍树"); 
        }
    
    }
    
  3. 测试

    @Test
    public void testClothes() {
        Worker worker = ctx.getBean("worker",
                Worker.class);
        System.out.println(worker.getClothes());
    }
    

混合使用 注解和xml文件

可以用声明bean组件注入到注解标注的属性,也可以将注解声明的Bean注解注入到 属性中。

  1. 编写类:

    public class Gun {
    
        public String toString() {
            return "98k"; 
        }
    }
    
  2. 利用 声明Bean组件

    <bean id="gun" class="day03.Gun"></bean>
    
  3. 重构Worker

    @Component
    public class Worker {
        @Autowired
        private Tool tool;
    
        //Clothes 衣服
        private Clothes clothes;
    
        @Autowired
        private Gun gun;
    
        public Worker() {
            name="光头强";
        }
    
        @Autowired
        public void setClothes(Clothes clothes) {
            this.clothes = clothes;
            System.out.println("setClothes()"+clothes);
        }
    
        public Clothes getClothes() {
            return clothes;
        }
    
        public Gun getGun() {
            return gun;
        }
    
        public void work() {
            System.out.println(name+"使用"+tool+"砍树"); 
        }
    
    }
    
  4. 测试

    @Test
    public void testGun() {
        Worker worker = ctx.getBean("worker",
                Worker.class);
        System.out.println(worker.getGun());
    }
    

@Value

@Value用于为属性注入基本值,经常与Spring表达式配合实现读取配置文件

  1. 编写配置文件 config.properties

    name=\u5C0F\u5F3A
    

    其中\u5C0F\u5F3A是中文 “小强” 的Unicode转码

  2. 利用配置文件读取properties

    <util:properties id="config"
        location="classpath:config.properties"/>
    
  3. 重构Worker注入属性

    @Component
    public class Worker {
        //@Autowired
        @Resource
        private Tool tool;
    
        //Clothes 衣服
        private Clothes clothes;
    
        @Autowired
        private Gun gun;
    
        @Value("#{config.name}") 
        private String name;
    
        public Worker() {
            name="光头强";
        }
    
        //@Autowired
        @Resource
        public void setClothes(Clothes clothes) {
            this.clothes = clothes;
            System.out.println("setClothes()"+clothes);
        }
    
        public Clothes getClothes() {
            return clothes;
        }
    
        public Gun getGun() {
            return gun;
        }
    
        public void work() {
            System.out.println(name+"使用"+tool+"砍树"); 
        }
    
    }
    
  4. 回归测试

    @Test
    public void testWorker() {
        //Spring:解析注解,控制对象,注入属性,属性不是空
        Worker worker = ctx.getBean("worker",
                Worker.class);
        worker.work();
        //脱离Spring容器自己创建对象,无人解析属性,
        //无人注入属性,属性为空
        Worker worker2 = new Worker();
        worker2.work();
    }
    

Spring MVC

Spring在Spring基础之上提供了Spring MVC 框架,Spring + Spring MVC + MyBatis 合称 SSM 框架。

  1. Web框架是Web软件的半成品,Web框架封装了Web应用程序中大部分技术细节,利用Web框架开发软件快速高效。 使用广泛。
  2. Web框架不是必须品,Web软件完全可以不采用Web框架。有些企业会创建自己的框架级解决方案。
  3. 使用Web框架必须按照Web的约定使用才能做到事半功倍的效果。

使用Spring MVC 步骤

  1. 导入Spring MVC相关包
  2. 配置前端控制器
  3. 编写配置文件
    1. 配置视图解析器
  4. 编写子控制器
  5. 编写视图页面

Spring MVC 的请求流程:

使用Spring MVC

  1. 导入包

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.10.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>
    
    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.3.2</version>
    </dependency>
    
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>  
    

    这里也导入了项目必须依赖的其他包。

  2. 配置前端控制器 web.xml

    <servlet>
        <description></description>
        <display-name>DispatcherServlet</display-name>
        <servlet-name>DispatcherServlet</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>DispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    

    将*.do请求全部转到 前端控制器

  3. 编写Spring MVC 配置文件 mvc.xml

    <!-- 扫描控制器组件 -->
    <context:component-scan 
        base-package="controller"/>
    
    <!-- 通知HandlerMapping,处理RequestMapping注解 -->
    <mvc:annotation-driven/>
    
    <!-- 视图处理器 
        当控制器返回视图名称时候,利用视图解析器拼接
        前后缀,找到视图对象
        如: 控制器返回 view 时候,拼接前后缀以后
           /WEB-INF/jsp/view.jsp 用于定位jsp文件 -->
    <bean id="viewResolver" 
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- prefix: 前缀, suffer:后缀-->
        <property name="prefix" 
            value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    
  4. 编写控制器

    @Controller
    public class HelloController {
    
        @RequestMapping("/demo.do")
        public String execute() {
            System.out.println("Hello World!"); 
            return "view"; // view.jsp
        }
    
    }
    
  5. 编写视图 /WEB-INF/jsp/view.jsp

    <%@ page language="java" 
        contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="">
    <title>View</title>
    </head>
    <body>
        <h1>Hello World!</h1>
    </body>
    </html>
    
  6. 测试。

控制器向JSP传送数据

Spring利用ModelAndView封装数据,并且传递JSP,这种封装的好处是将控制器与Request解耦,使控制器可以进行单独的测试。

原理:

案例:

  1. 编写控制器:

    //将控制器中的计算结果传递到JSP
    @RequestMapping("/test.do")
    public ModelAndView test() {
        //创建一个Map存储显示数据
        //用string 代表显示的视图
        Map<String, Object> model = 
                new HashMap<String, Object>(); 
        String view="test";
        model.put("message", "Hello Spring MVC");
        return new ModelAndView(view, model); 
    }
    
  2. 编写JSP /WEB-INF/jsp/test.jsp

    <%@ page language="java" 
        contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="">
    <title>View</title>
    </head>
    <body>
        <h1>从控制器传送数据到视图</h1>
        <p>${message}</p>
    </body>
    </html>
    
  3. 测试

利用ModelMap传递数据到JSP

  1. 编写控制器

    //利用ModelMap传递参数到JSP页面
    @RequestMapping("/test2.do")
    public String test2(ModelMap model) {
        model.put("message", "test2");
        return "test"; //test.jsp
    }
    
  2. 测试

案例显示用户列表

  1. 编写用户实体类

    public class User implements Serializable {
    
        private String name;
        private int age;
        private String email;
    
        public User() {
        }
    
        public User(String name, int age, String email) {
            super();
            this.name = name;
            this.age = age;
            this.email = email;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        @Override
        public String toString() {
            return "User [name=" + name + ", age=" + age + ", email=" + email + "]";
        }
    
    }
    
  2. 编写控制器

    @RequestMapping("/list.do")
    public String list(ModelMap model) {
        List<User> users=new ArrayList<User>();
        users.add(new User("光头强", 40, "110@tedu.cn"));
        users.add(new User("王宝强", 32, "120@tedu.cn"));
        users.add(new User("马蓉", 30, "119@tedu.cn"));
        users.add(new User("老宋", 22, "123@tedu.cn"));
        //向页面传送数据
        model.put("users", users);
        return "list"; 
    }
    
  3. 引入JSTL

    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>       
    
  4. 编写视图 list.jsp

    <%@ page language="java" 
        contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" 
        uri="http://java.sun.com/jsp/jstl/core" %> 
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="">
    <title>用户列表</title>
    </head>
    <body>
        <h1>用户列表</h1>
        <ul>
            <c:forEach items="${users}" var="user">
                <li>${user.name}, ${user.age}, ${user.email}</li>
            </c:forEach>
        </ul>
    </body>
    </html>
    
  5. 测试