一站式应用开发框架-Spring使用方法总结

Spring 4.x

1. Spring Boot

Spring Boot用于快速开启一个Spring项目:

  1. 通过Maven方式新建一个项目
  2. pom.xml中指定parent为spring-boot-starter-parent
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.3.RELEASE</version>
</parent>
  1. 依赖starter,书本p51-p52有介绍不同的starter,此处为了支持Web应用和数据库开发导入了spring-boot-starter-webspring-boot-starter-jdbc(connector-j需要另外导入,右键Diagrams显示依赖,可以看到依赖了什么库):
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>${boot.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>
  1. 定义Application,使用@SpringBootApplication代替@Configuration@ComponentScan@EnableAutoConfiguration三个注解,@EnableTransactionManagement表示支持事务,继承SpringBootServletInitializer重写confiura()方法以支持Spring MVC
@SpringBootApplication
@EnableTransactionManagement
public class Application extends SpringBootServletInitializer {
   
    public static void main(String[] args) {
   
        SpringApplication.run(Application.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
   
        return builder.sources(Application.class);
    }
}
  1. 在resource下创建application.properties,配置数据库链接、tomcat、jsp:
spring.datasource.url=jdbc:mysql://localhost:3306/sampledb?serverTimezone=GMT
spring.datasource.username=zhangyijun
spring.datasource.password=mysql1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.tomcat.max-idle=10
spring.datasource.tomcat.min-idle=8
spring.datasource.tomcat.max-wait=1000
spring.datasource.tomcat.max-active=100
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validation-query=select 1

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
  1. 编写Controller,使用注解@RestController@RequestMapping
@RestController
public class LoginController {
   
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
   
        this.userService = userService;
    }

    @RequestMapping(value = {
   "/hello", "/index.html"})
    public ModelAndView loginPage() {
   
        return new ModelAndView("login");
    }

    @RequestMapping(value = "/loginCheck.html")
    public ModelAndView loginCheck(HttpServletRequest request, LoginCommand loginCommand) {
   
        boolean isValidUser = userService.hasMatchUser(loginCommand.getUserName(), loginCommand.getPassword());
        if (!isValidUser) {
   
            return new ModelAndView("login", "error", "用户名或密码错误");
        } else {
   
            User user = userService.findUserByUserName(loginCommand.getUserName());
            user.setLastIp(request.getLocalAddr());
            user.setLastVisit(new Date());
            userService.loginSuccess(user);
            request.getSession().setAttribute("user", user);
            return new ModelAndView("main");
        }
    }

}
  1. 编写剩余代码,JdbcTemplate注入到Dao中,Dao注入到Service中,Service注入到Controller中

2. IoC容器

2.1 ApplicationContext

2.1.1 AnnotationConfigApplicationContext
  • 拥有@Bean注解方法的类 User:
@Bean(name = "DefaultUser")
public User buildUser() {
   
    return User.builder()
            .userId(123)
            .userName("in annotation @Bean")
            .password("123")
            .credits(123)
            .lastIp("127.0.0.1")
            .lastVisit(new Date())
            .build();
}
  • 通过构造器传入上面的类
  • 使用<T> T getBean(String name, Class<T> requiredType)方法获取bean:
ApplicationContext context = new AnnotationConfigApplicationContext(User.class);
User user = context.getBean("DefaultUser", User.class);
2.1.2 ClassPathXmlApplicationContext
public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
   

}
  • 通过构造器传入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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="date" class="java.util.Date"/>

    <bean id="user" class="com.smart.domain.User"
          p:userId="1"
          p:userName="in xml file: beans.xml"
          p:password="asd"
          p:credits="123"
          p:lastIp="1.1.1.1"
          p:lastVisit-ref="date"/>

</beans>
val context = new ClassPathXmlApplicationContext("classpath:beans.xml");
val user = context.getBean("user", User.class);
  • "classpath:beans.xml"此处可以简写为"beans.xml"
  • beans.xml放在了resources文件夹下

2.2 生命周期

BeanFactoryApplicationContext的生命周期类似,BeanFactory在调用getBean(beanName)的时候开始生命周期,ApplicationContext在容器开启的时候一次性初始化所有Bean(可以通过@Lazy注解实现懒加载):

  1. InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()
  2. 实例化
  3. InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
  4. InstantiationAwareBeanPostProcessor#postProcessPropertyValues()
  5. 设置属性值
  6. BeanNameAware#setBeanName()
  7. BeanFactoryAware#setBeanFactory()
  8. BeanPostProcessor#postProcessBeforeInitialization()
  9. InitializingBean#afterPropertiesSet()
  10. init-method
  11. BeanPostProcessor#postProcessAfterInitialization()
  12. scope
    1. singleton Spring缓存池中准备就绪的Bean
    2. prototype 将准备就绪的Bean交给调用者
  13. 容器销毁,调用DisposableBean中的destroy()方法
  14. destory-method
  • 通过在<bean>标签中定义init-methoddestory-method,因为对象实例化和属性初始化的原因,这两个方法的生命周期都比较靠后
  • 通过注解@PreDestroy@PostConstrut修饰方法

3. 在IoC容器中装配Bean

3.1 Setter注入

  • 需要提供对应的setter方法,并且id或name前两个字母要么都是大写,要么都是小写
public class User{
   
    private String name;
    public void setName(String name){
   
        this.name = name;
    }
}
<bean id="user" class="com.smart.domain.User" p:name="1"/>

3.2 Construct注入

  • 最好用index+type指定入参
<bean id="user1" class="com.smart.domain.User">
    <constructor-arg index="0" type="int" value="1"/>
    <constructor-arg index="1" type="java.lang.String" value="1"/>
    <constructor-arg index="2" type="java.lang.String" value="1"/>
    <constructor-arg index="3" type="int" value="1"/>
    <constructor-arg index="4" type="java.lang.String" value="1123"/>
    <constructor-arg index="5" type="java.util.Date" ref="date"/>
</bean>

3.3 Factory注入

  • 如果工厂提供静态方法,则把factory-bean换成class指定工厂类就行了
<bean id="userFactory" class="com.smart.factory.UserFactory"/>
<bean id="user" factory-bean="userFactory" factory-method="createUser"/>
<!--静态0-->
<bean id="user" class="com.smart.factory.UserFactory" factory-method="createUser"/>

3.4 内部Bean

  • 作用域为prototype
<bean id="boss" class="com.smart.attr.Boss">
    <property name="car">
        <bean class="com.smart.attr.Car">
            <property name="maxSpeed" value="200"/>
            <property name="price" value="2000.00"/>
        </bean>
    </property>
</bean>

3.5 注入null

<bean id="boss" class="com.smart.attr.Boss">
    <property name="car">
        <null/>
    </property>
</bean>

3.6 注入集合

  • 可以引入util命名空间来显式指定实现类
<bean id="boss" class="com.smart.attr.Boss">
    <!-- list/数组-->
    <!--<property name="carList">-->
    <!--    <list>-->
    <!--        <value>ferrari</value>-->
    <!--        <value>maserati</value>-->
    <!--        <value>porsche</value>-->
    <!--    </list>-->
    <!--</property>-->
    
    <!-- util命名空间指定list-->
    <util:list id="carList" list-class="java.util.LinkedList">
       <value>ferrari</value>
       <value>maserati</value>
       <value>porsche</value>
    </util:list>
    
    <!-- Set-->
    <property name="carSet">
        <set>
            <value>ferrari</value>
            <value>maserati</value>
            <value>porsche</value>
        </set>
    </property>
    
    <!-- Map-->
    <property name="carMap"
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值