华清远见-重庆中心-框架技术总结

框架是一套规范。

实际是他人实现的一系列接口和类的集合。通过导入对应框架的jar文件(Maven项目导入对应的依赖),进行适当的配置,就能使用其中的所有内容。开发者可以省去很多模板代码

Spring

是一个轻量级开源的Java框架,是一个管理项目中对象的容器,也是其他框架的粘合器,目的就是对项目进行解耦

核心:IOC控制反转和AOP面向切面编程

控制反转是一种思想,就是让创建对象的控制权由自身交给第三方,控制翻转这种思想,通过依赖注入的方式实现

bean标签常用属性

属性

作用

class

定义类的全限定名

id

定义对象的名称

lazy-init

设置是否为懒加载,默认值为false,在解析配置文件时就会创建对象。设置为true表示懒加载,只有在getBean()时才会创建对象。

scope

单例/原型模式。默认值为singleton,表示单例模式,只会创建一个对象。设置为prototype,表示原型模式,每次调用getBean()就会创建一个对象

init-method

初始化方法,在创建完该对象时自动调用的方法,该方法只能是无参方法,该属性的值只需要写方法名即可

destory-method

销毁时触发的方法。Spring容器关闭时自动调用的方法,该方法只能是无参方法,只有在单例模式下有效

属性注入

给某个bean标签添加属性的两种方式:setter注入和构造器注入

setter注入

该方法注入属性时,类中必须要有set方法

该标签的name属性通常表示该对象的某个属性名,但实际是setXXX()方法中的XXX单词。

该标签的value属性表示给该类中的某个属性赋值,该属性的类型为原始类型或String。

<!--注入Car类对象,并用set方式注入其属性-->
<bean class="com.hqyj.SetterInject.Car" id="c">
    <!--该属性是字符串类型或原始类型,使用value-->
    <property name="brand" value="宝马"></property>
    <property name="color" value="白色"></property>
</bean>

构造器注入

这种方式注入属性时,类中必须有相应的构造方法(有参)

该标签的name属性表示构造方法的参数名,index属性表示构造方法的参数索引。

赋值时,原始类型和字符串用value,引用类型用ref。

<!--注入Person类对象 并用构造方法注入其属性-->
<bean class="com.hqyj.SetterInject.Person" id="p2">
    <!--constructor-arg表示构造方法参数name是参数名 index是参数索引-->
    <constructor-arg name="name" value="张三"></constructor-arg>
    <constructor-arg index="1" value="23"></constructor-arg>
    <!--c是Car类的对象-->
    <constructor-arg name="car" ref="c" ></constructor-arg>
</bean>

复杂属性注入

public class Movie {
    private String movieName;//电影名
    private String director;//导演
    private int duration;//时长
    private List<String> playerList;//主演
    private String movieType;//电影类型
    private String showTime;//放映时间:最终格式为yyyy/MM/dd HH:mm:ss
    //忽略了setter/getter/gouzao方法等
}
List类型属性注入
<!--注入movie对象-->
<bean class="com.hqyj.SetterInject.Movie" id="movie1">
    <property name="movieName" value="夏洛特烦恼"></property>
    <property name="director" value="闫飞彭大魔"></property>
    <property name="duration" value="87"></property>
    <!--List类型属性赋值-->
    <property name="playerList">
        <!--使用list标签-->
        <list>
            <!-- 如果集合中保存的是引用类型,使用ref标签-->
            <!--如果集合中保存的是原始类型或字符申,使用value标签-->
            <value>沈腾</value>
            <value>马丽</value>
            <value>艾伦</value>
        </list>
    </property>
    <property name="movieType" value="戏剧"></property>
    <property name="showTime" value="2020/06/10 0:0:0"></property>
</bean>
Set类型属性注入
//宠物类
public class Pet {

    private String petType;
    private String petNickName;
    private int petAge;

    public Pet(String petType, String petNickName, int petAge) {
        this.petType = petType;
        this.petNickName = petNickName;
        this.petAge = petAge;
    }
    //省略了setter/getter/toString方法
    public Pet() {
    }
}

//宠物店类
public class PetShop {
    private String shopName;
    private Set<Pet> petList;

    public PetShop(String shopName, Set<Pet> petList) {
        this.shopName = shopName;
        this.petList = petList;
    }
    //省略了setter/getter/toString方法
    public PetShop() {
    }
}

注入:

<bean class="com.hqyj.SetInject.Pet" id="pet1">
    <property name="petType" value="二哈"></property>
    <property name="petNickName" value="乐乐"></property>
    <property name="petAge" value="3"></property>
</bean>
<bean class="com.hqyj.SetInject.Pet" id="pet2">
    <property name="petType" value="金毛"></property>
    <property name="petNickName" value="linck"></property>
    <property name="petAge" value="2"></property>
</bean>

<bean class="com.hqyj.SetInject.PetShop" id="petShop">
    <property name="shopName" value="狗狗乐园"></property>
    <property name="petList">
        <set>
            <ref bean="pet1"></ref>
            <ref bean="pet2"></ref>
        </set>
    </property>
</bean>

Map属性注入

<!--实体类-->
public class Cinema {
    private String name;
    <!--定义Map保存上映时间表,键是影厅号,值是电影对象-->
    private Map<Integer,Movie> timeTable;

    public Cinema(String name, Map<Integer, Movie> timeTable) {
        this.name = name;
        this.timeTable = timeTable;
    }

    public Cinema() {
    }
    <!--省略了toString()、getter()、getter()方法-->
}
<!--注入Cinema对象-->
<bean class="com.hqyj.SetterInject.Cinema" id="cinema">
    <property name="name" value="万达影城"></property>
    <property name="timeTable">
        <!--Map类型属性赋值,标明键和值的类型-->
        <map key-type="java.lang.Integer" value-type="com.hqyj.SetterInject.Movie">
            <!--entry标签表示键值对如果键值对都是原始类型或字符串,使用key和value-->
            <!--如果键值对中有引用类型,使用key-ref或value-ref-->
            <entry key="1" value-ref="movie1"></entry>
            <entry key="2" value-ref="movie2"></entry>
        </map>
    </property>
</bean>
现在时间注入
<!--注入SimpleDateFormat对象,设置日期格式-->
<bean class="java.text.SimpleDateFormat" id="sdf">
    <!--如果构造方法注入时,该构造方法只有一个参数,可以不用name或index-->
    <constructor-arg index="0" value="yyyy/MM/dd"></constructor-arg>
</bean>
<!--注入Date对象--> .
<bean class="java.util.Date" id="now"></bean>

<bean class="com.hqyj.SetterInject.Movie" id="movie1">
    <property name="类中的时间属性名">
        <bean factory-bean="sdf" factory-method="format">
            <constructor-arg ref="now"></constructor-arg>
        </bean>
    </property>
</bean>

属性自动注入autowire

实现自动注入

在某个bean标签中,加入autowire属性,设置值为"byName"或"byType",通常设置为"byType"

public class Car {
    private String brand;
    private String color;

    public Car(String brand, String color) {
        this.brand = brand;
        this.color = color;
    }

    public Car() {
    }

    //省略了setter/getter/toString方法
}

//Person类
public class Person {
    private String name;
    private int age;
    private Car car;

    public Person(String name, int age,Car car) {
        this.name = name;
        this.age = age;
        this.car = car;
    }

    public Person() {
    }
    //省略了setter/getter/toString方法
}

配置文件:

<!--在容器中注入Car类型的bean-->
<bean class="com.hqyj.SetterInject.Car" id="car">
     <property name="brand" value="宝马"></property>
     <property name="color" value="白色"></property>
</bean>

<!--注入Person类的bean-->
<!--autowire="byType "表示自动检测该类中是否需要使用引用类型参数,如果容器中正好有唯一的一个对应类型的bean, 就会自动赋值给对应的属性-->
<bean class="com.hqyj.AutoWire.Person" id="person" autowire="byType">
    <property name="name" value="王海"></property>
    <property name="age" value="45"></property>
</bean>

<!--autowire="byName"表示自动检测该类中的setxxx方法,如果某个setxxx方法的x和容器某个对象的id对应,就会自动赋值给对应的属性-->
<bean class="com.hqyj.AutoWire.Person" id="person2" autowire="byName">
    <property name="name" value="王海"></property>
    <property name="age" value="45"></property>
</bean>

主方法:

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
    Person person = context.getBean("person", Person.class);
    System.out.println(person);
    context.close();
}
autowire属性的值

byType

  • 类中要有被注入的属性的setter()方法

  • 被自动注入的对象可以没有id

  • Spring容器中,某个对象的类型要与该setter()方法的参数类型-致,且容器中只有一个该类型的对象

  • 如setCar(Car C), Spring就会自动在容器中寻找类型为Car的对象自动装配

byName

  • 类中要有被注入的属性的setter()方法

  • 被自动注入的对象必须要有id

  • 实际是根据setXXX()方法set后的单词XXX关联

  • 如setCar(Car c),Spring就会自动在容器中寻找id为car的对象自动装配

Spring核心注解

在spring配置文件中进行配置:

 <!--如果要使用Spring注解,需要加入这段话,表示扫描指定包下所有使用了注解的类-->
<context:component-scan base-package="com.hqyj.Seconds.bookSystem"></context:component-scan>

BookDao类:

//这个注解相当于在配置文件中加入<bean class= "com.hqyj.Seconds.bookSystem.dao.BookDao"></bean>
@Component
publicclassBookDao {
    publicvoidqueryAll(){
        System.out.println("模拟查询所有图书信息");
    }
}

BookService类

@Component//这个注解相当于在配置文件中加入<bean class= "com.hqyj.Seconds.bookSystem.service.BookServicel"></bean>
publicclassBookService {
    @Autowired//这个注解相当于<bean class= "com.hqyj.Seconds.bookSystem.service.BookServicel"></bean>中加入autowire=byType
    privateBookDaobookDao;
​
    publicvoidshowAll(){
        System.out.println("经过service执行dao中的方法");
        bookDao.queryAll();
    }
}

BookController类

//如果没有设置名称,获取当前类的对象,名称为类名的驼峰俞名法形式。如BookController, 获取时使用bookController获取
@Component
//这里的value表示给该bean设置id名,调用时使用controller
//@Component(value = "controller")
publicclassBookController {
    @Autowired
    privateBookServicebookService;
    publicvoidshowAll(){
        System.out.println("经过controller,调用service中的方法");
        bookService.showAll();
    }
}

Main方法

publicclassBookMain {
    publicstaticvoidmain(String[] args) {
        ClassPathXmlApplicationContextcontext=newClassPathXmlApplicationContext("book_system.xml");
        //BookController类中使用@Component注解时使用
        BookControllerbean=context.getBean("bookController",BookController.class);
        //BookController类中使用@Component(value="controller")或者@Controller(value = "controller")注解时使用
        //BookController bean = context.getBean("controller",BookController.class);
        bean.showAll();
    }
}

类上加的注解

  • @Component

  • 当一个类不好归纳时,使用该注解定义为普通组件

  • @Controller

  • 定义一个类为控制层组件

  • @Service

  • 定义一个类为业务逻辑层组件

  • @Repository

  • 定义一个类为持久层(数据访问层/dao层)组件

  • @Lazy/@Lazy(value=true)

  • 设置该类为懒加载

  • @Scope/@Scope(valuye="singleton/prototype")

  • 设置为单例/原型模式,默认单例模式

说明

以上注解的公共特点

  • 都是将对应类的对象注入到Spring容器中,用于替换配置文件中的bean标签

  • 默认是单例模式,只会创建一个对象,非懒加载,容器加载时会自动创建。

  • 默认注入的对象id为当前类的类名首字母小写形式

  • 如在BookDao类上添加@Component,id默认为bookDao

  • 可以通过注解的value属性自定义注入的对象的id名,如@Component(value="key")表示注入的对象id为key

属性上加的注解

  • @Autowired

  • 优先使用byType方式从Spring容器中获取对应类型的对象自动装配,先检索Spring容器中对应类型的数量。如果数量为0,直接报错;如果数量为1直接装配;如果有多个对应类型的对象,会尝试使用byName方式获取对应的id对象,但要配合@Qualifier(value=""某个对象的id)一起使用,指定id进行装配。

  • @Qualifier(value="某个对象的id")

  • 配合@Autowired注解,使用byName方式获取某个对象id的bean进行装配

  • @Resource(name="某个对象的id")

  • 该注解相当于@Autowired+@Qualifier(value="某个对象的id")

  • 优先以byName的方式,从spring容器中检索出name为指定名的对象进行装配,如果没有则尝试byType方式,要求对象有且只有一个,否则也会报错。

说明
  • 如果要在某个类中使用spring容器中的某个对象时,只需定义成员变量,无需创建对象,通过@Autowired或@Resource注解进行自动装配

  • 实际开发中,绝大部分情况下,需要自动装配对象有且只有一个,并且命名规范,所以@Autowired或@Resource区别不是很大。@Autowired优先byType方式,@Resource优先使用byName方式。

  • 如果@Resource不能使用,是因为缺少javax.annotation包,需要引入对应依赖

<!--pom.xml-->
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</ dependency>

web项目中使用Spring

添加依赖

<!--servlet-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
</dependency>

<!--spring容器-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.23</version>
</dependency>
<!--web集成-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.23</version>
</dependency>

在main目录下创建java和resources目录,修改web.xml版本为4.0


在resources目录下创建spring配置文件application.xml,扫描使用了注解的根包

<context:component-scan base-package="com.hqyj.springweb"></context:component-scan>

创建一个类,使用@Componet注解将其注入到Spring容器中

@Component
public class Pojo {
    public void fun(){
        System.out.println("hello springweb");
    }
}

配置监听器用于初始化Spring容器

<!--配置全局监听器用于初始化Spring容器-->
<listener>
    <!--ContextLoaderListener是一个全局监听器-->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--定义全局参数-->
<context-param>
    <!--该监听器需要设置要读取的Spring配置文件路径-->
    <param-name>contextConfigLocation</param-name>
    <!--只是Spring配置文件的路径c1asspath:表示从根目录出发-->
    <param-value>classpath:application.xml</param-value>
</context-param>

创建一个servlet,范围跟该servlet,获取spring容器,从容器中获取

@org.springframework.stereotype.Controller
@WebServlet("/hello")
public class MyController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Spring容器
        WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        //从容器中获取某个bean
        Pojo pojo = context.getBean("pojo", Pojo.class);
        pojo.fun();
    }
}

如何初始化spring容器

实际就是如何在web应用中解析Spring的配置文件

在控制台应用程序中,可以在main方法中通过ClassPathXmlApplicationContext来解析application.xml文件, 初始化Spring容器。

在web项目中没有main方法,只有servlet中的service,如果在service方法中创建ClassPathXmlApplicationContext对象,会每次访问都执行

而Spring容器只需初始化一次,在项目启动时就解析application.xml文件,全局监听器就是一个很好的选择。

spring-web包中提供了一个ContextLoaderListener类, 它实现了ServletContextListener,属于项目级别的全局监听器。

这个类需要一个contextConfigLocation参数,表示要解析的application.xml文件的路径。

这个监听器会在项目启动时,读取指定的Spring配置文件路径,并且创建WebApplicationContext对象,即Spring容器, 这个对象保存在ServletContext中

在spring-web项目中使用Spring-jdbc

1.添加依赖

<dependencies>
    <!--servlet-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
    </dependency>

    <!--spring容器-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.23</version>
    </dependency>
    <!--web集成-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.3.23</version>
    </dependency>

    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.31</version>
    </dependency>

    <!--jstl-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!--spring-jdbc-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.23</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
</dependencies>

2.创建包结构(controller、servlet、dao、entity),创建实体类

publicclassHero {
    privateintid;
    privateStringname;
    privateStringposition;
    privateStringsex;
    private  intprice;
    privateStringshelfDate;
​
    publicHero(intid, Stringname, Stringposition, Stringsex, intprice, StringshelfDate) {
        this.id=id;
        this.name=name;
        this.position=position;
        this.sex=sex;
        this.price=price;
        this.shelfDate=shelfDate;
    }
​
    publicHero(Stringname, Stringposition, Stringsex, intprice, StringshelfDate) {
        this.name=name;
        this.position=position;
        this.sex=sex;
        this.price=price;
        this.shelfDate=shelfDate;
    }
    publicHero() {
    }
    //忽略setter/getter/toString方法
}

3.在spring配置文件中配置数据源和JDBC模板

<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="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:component-scanbase-package="com.hqyj.springweb"></context:component-scan>
​
    <!--配置数据库-->
    <beanclass="org.springframework.jdbc.datasource.DriverManagerDataSource"id="dataSource">
        <!--配置连接驱动-->
        <propertyname="driverClassName"value="com.mysql.cj.jdbc.Driver"></property>
        <!--配置mysql地址-->
        <propertyname="url"value="jdbc:mysql://localhost:3306/gamedb?serverTimezone=Asia/Shanghai"></property>
        <propertyname="username"value="root"></property>
        <propertyname="password"value="123456"></property>
    </bean>
​
    <!--配置JDBC模板-->
    <beanclass="org.springframework.jdbc.core.JdbcTemplate"id="jdbcTemplate">
        <!--设置要操作的数据源-->
        <propertyname="dataSource"ref="dataSource"></property>
    </bean>
</beans>

4.数据访问层(dao)的写法

@Repository
publicclassHeroDao {
    @Autowired
    //通过jdbc模板对象实现CRUD
    privateJdbcTemplatejdbcTemplate;
​
    publicList<Hero>queryAll() {
        Stringsql="select * from hero";
        //BeanPropertyRowMapper对象表示将查询到的字段与指定的类中的属性进行映射
        BeanPropertyRowMapper<Hero>mapper=newBeanPropertyRowMapper<>(Hero.class);
        //query()方法执行查询
        List<Hero>list=jdbcTemplate.query(sql, mapper);
        returnlist;
    }
​
    publicbooleandelete(intid) {
        Stringsql="delete from hero where id=?";
        inti=jdbcTemplate.update(sql, id);
        returni>0;
    }
​
    publicbooleaninsert(Herohero){
        Stringsql="insert into hero values(null,?,?,?,?,?)";
        intinsert=jdbcTemplate.update(sql, hero.getName(), hero.getPosition(), hero.getSex(), hero.getPrice(), hero.getShelfDate());
        returninsert>0;
    }
​
    publicHerofindById(intid){
        Stringsql="select * from hero where id=?";
        BeanPropertyRowMapper<Hero>mapper=newBeanPropertyRowMapper<>(Hero.class);
        Herohero=jdbcTemplate.queryForObject(sql, mapper, id);
        returnhero;
    }
​
    publicbooleanupdate(Herohero){
        Stringsql="update hero set name=?,position=?,sex=?,price=?,shelf_date=? where id=?";
        intupdate=jdbcTemplate.update(sql, hero.getName(), hero.getPosition(), hero.getSex(), hero.getPrice(), hero.getShelfDate(), hero.getId());
        returnupdate>0;
    }
}​

5.控制层(controller)写法

@WebServlet("/hero")
publicclassHeroServletextendsHttpServlet {
    @Override
    protectedvoidservice(HttpServletRequestreq, HttpServletResponseresp) throwsServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //获取Spring容器,获取HeroDao对象
       
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值