Spring 注解回顾

小区物业管理系统 我新建了两个点java文件,一个是com.action中的WyServlet.java一个是com.bean中的TraveBean.java。它们的功能主要是对表的增删改查,但增加和更新功能我并没有挨个写只写了其中的几个,其余的大体一样只要改改字段和表名就ok了,如果你感觉有必要挨个写上,那就在加上就行了。还有数据库中我新建了几个表,但有的也没用到。 立即下载

在回顾ssm各个注解前,我们先对xml中配置的下面三个内容做简单回顾:

<context:annotation-config/>

<context:component-scan/>

<mvc:annotation-driven/>

1.<context:annotation-config/> 隐式地向 Spring容器注册这4个BeanPostProcessor :

AutowiredAnnotationBeanPostProcessor
    @Autowired
RequiredAnnotationBeanPostProcessor
    @Required
CommonAnnotationBeanPostProcessor
    @Resource 、@PostConstruct、@PreDestroy
PersistenceAnnotationBeanPostProcessor
    @PersistenceContext

<context:annotation-config/>是用来使上述注解起作用的,也就是说激活已经在application context中注册的bean。之所以这样说是因为<context:annotation-config />仅能够在已经注册过的bean上面起作用。对于没有在spring容器中注册的bean,它并不能执行任何操作, 也就是说如果你并没有在spring容器中注册过bean(spring配置文件中配置bean就是注册(也就是说spring中不存在你想使用的bean)),那么上述的那些注解并不会在你未注册过的bean中起作用, 注意这些属性一般都是注册在bean中的字段或者方法上;

2.<context:component-scan base-package="com.zit,com.qian.dao"/>

<context:component-scan>做了<context:annotation-config>要做的事情,还额外支持@Component,@Repository,@Service,@Controller @RestController, @ControllerAdvice, and @Configuration 注解(注意这些注解一般都是注解在class上)。并且<context:component-scan>扫描base-package时会把扫描到的使用注解bean在application context中进行注册。也就是<context:component-scan>该注解可以扫描并注册你使用注解诸如@controller @service @component..的bean!!!

所以配置<context:component-scan>就不需要配置<context:annotation- config/>

3. <mvc:annotation-driven/>

对应的实现类为:org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser

<mvc:annotation-driven/>隐式的向beanFactory中注册如下类

用于处理请求映射的
    其中第一个是处理@RequestMapping注解的。
    第二个会将controller类的名字映射为请求url。
RequestMappingHandlerMapping
BeanNameUrlHandlerMapping

中间三个是用来处理请求的
    第一个处理@Controller注解的处理器,支持自定义方法参数和返回值(很酷)。
    第二个是处理继承HttpRequestHandler的处理器。
    第三个处理继承自Controller接口的处理器。
RequestMappingHandlerAdapter
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter

后面三个是用来处理异常的解析器
ExceptionHandlerExceptionResolver
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver 

此外还支持如下功能:

① 支持使用ConversionService实例对表单参数进行类型转换;
② 支持使用@NumberFormatannotation、@DateTimeFormat注解完成数据类型的格式化;
③ 支持使用@Valid注解对Java bean实例进行JSR 303验证;
④ 支持使用@RequestBody和@ResponseBody注解

上述内容整理自以下几篇博文:

https://blog.youkuaiyun.com/j080624/article/details/60883328

https://blog.youkuaiyun.com/j080624/article/details/60883328

关于注解的辅助知识:

首先,spring在读取到注解标注的 Bean 时,如果Bean没有命名,就会自动将 bean 的类名的首字符转成小写,作为Bean的 id;

其次,关于Spring bean的 name  和 id 的几点说明:

(1)每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一;

(2)如果不指定id,只指定name,那么name为Bean的标识符,并且需要在容器中唯一;

(3)同时指定name和id,此时id为标识符,而name为Bean的别名,两者都可以找到目标Bean;

(4)可以指定多个name,之间可以用分号、空格或逗号隔开,如果没有指定id,那么第一个name为标识符,其余的为别名;若指定了id属性,则id为标识符,所有的name均为别名;

(5)在xml配置文件中:如果id和name都没有指定,则用类全名作为name,如<bean class="com.stamen.BeanLifeCycleImpl">,则你可以通过getBean("com.stamen.BeanLifeCycleImpl")返回该实例;

(6)在xml配置文件中:如果存在多个id和name都没有指定,且 实例类 都一样的,例如:<bean class="com.stamen.BeanLifeCycleImpl"> <bean class="com.stamen.BeanLifeCycleImpl">,则第一个bean通过getBean(“com.stamen.BeanLifeCycleImpl”) 获得,第二个bean通过getBean(“com.stamen.BeanLifeCycleImpl#1”)获得,以此类推。

(7)在注解配置中:如果不指定bean的name,默认将类名首字母小写作为类的名字;

  • 注解《1》@Autowired

Autowired注解是Spring在2.5之后引入的,完成对类的 成员变量, set方法, 和构造函数进行自动注入,目的是减少类中出现的get set方法;

Autowired默认按类型注入, 当一个借口有多个实现类时,如何注入:通过如下示例进行说明:

// step1: 定义一个接口
public interface ImportService {
	void importInfo();
}

// step2: 定义接口的两个实现类和一个继承子类

/**
* 使用@Service注解标注,spring会自动管理这个Bean,并将
* 类名的首字母小写(xlsImportService)作为这个Bean的id;
* 也就是我们可以通过ctx.getBean("xlsImportService")来
* 找到这个bean;也可以通过@Resource("xlsImportService")
* 来自动注入这个bean
*/
@Service
public class XlsImportService implements ImportService {
	@Override
	public void importInfo() {
		System.out.println("XlsImportService");
	}
}

@Service
public class XlsImportServiceSon extends XlsImportService {
	@Override
	public void importInfo() {
		System.out.println("XlsImportServiceSon");
	}
}

@Service
public class TxtImportService implements ImportService {
	@Override
	public void importInfo() {
		System.out.println("TxtImportService");
	}
}

//step 3 建一个类来测试Autowried自动注入;

@Component
public class ComponentTest {
    /**
    * 失败:
    * 第一种注入方式:Autowired 注意此处引用名称为接口名首字母小写;
    * 报错:No qualifying bean of type [ImportService] is defined
    * 因为ImportService接口有三个子类,所以Spring通过类型注入时,
    * 不知道注入那个;
    */  
    @Autowired
    private ImportService importService;

    /**
    * 成功:
    * 第二种注入方式: Autowired 引用名称为某一个实现名首字母小写
    * 成功注入:TxtImportService实现;
    * 所以:当应用名字默认为接口实现ServiceBean的id名使,自动注入成功
    */
    @Autowired
    private ImportService txtImportService;
    
    /**
    * 成功:
    * 第三种注入方式: Autowired Qualifier("beanName")
    * 成功注入:XlsImportService实现;
    * 所以:当使用Autowired+Qualifier时,自动注入Qualifier中的beanName,
    * 与 接口后的引用名字txtImportService没有任何关系;
    */
    @Autowired
    @Qualifier("xlsImportService")
    private ImportService txtImportService;    
    
    /**
    * 成功:
    * 第四种注入方式: Resource 引用名为需注入bean的name名字
    * 成功注入:XlsImportServiceSon实现;
    * 所以:当使用Resource时,如果Resource(name)中省略name,将会以应用名
    *  “xlsImportServiceSon”作为bean的名字进行查找注入;
    */
    @Resource
    private ImportService xlsImportServiceSon; 
    
    /**
    * 成功:
    * 第五种注入方式: Resource(name="xlsImportService")
    * 成功注入:XlsImportService实现;
    * 所以:当使用Resource(name)时,将会以实例名为
    *  “xlsImportService”作为bean的名字进行查找注入;与引用的名字无关
    */
    @Resource
    private ImportService xlsImportServiceSon; 

    public void componentMethod(){
	xlsImportServiceSon.importInfo();
    }
}


总结:

(1)通常情况下@Autowired是通过byType的方法注入的,当有多个实现类的时候,byType的方式不再是唯一,而需要通过byName的方式来注入,而这个name默认就是根据变量名(应用名)来的。

(2)当一个接口有多个实现类时,通过 @Qualifier("beanName") 注解来指明使用哪一个实现类,实际上也是通过byName的方式实现。

(3)@Autowired(required=false)自动注入,如果找不到不报异常;

(4)当我们使用@Qualifier("beanName")或者@Resource("beanName)时,spring或按这个beanName进行对位查找,与接口后面的引用名字没有任何关系;

  • 注解《2》@Resource

@Resource(name="")
@Resource(type="")
@Resource
@Qualifier("");
默认 autowired by field name
如果 autowired by field name失败,会退化为 autowired by type
可以 通过@Qualifier 显式指定 autowired by qualifier name
如果 autowired by qualifier name失败,会退化为 autowired by field name。
但是这时候如果 autowired by field name失败,就不会再退化为autowired by type了。

@Autowired @Resource 和 @Inject 三个注解的区别:

(1)@Autowired是Spring提供的注解,其他几个都是JDK本身内建的注解,Spring对这些注解也进行了支持;

(2)@Autowired有个required属性,可以配置为false,这种情况下如果没有找到对应的bean是不会抛异常的。@Inject和 @Resource没有提供对应的配置,所以必须找到否则会抛异常。

(3)@Autowired和@Inject基本是一样的,因为两者都是使用AutowiredAnnotationBeanPostProcessor来处理依赖注入。但是@Resource是个例外,它使用的是CommonAnnotationBeanPostProcessor来处理依赖注入

  • 注解《3》@Controller @Service @Repository @Component

上面四个注解分别对应于 控制层,业务层,数据访问层 和 语义不明确的Bean的声明;

常见声明格式:

@Service
//不声明value则,将类名首字母小写作为Bean的名字默认:txtImportService
@Service(value="txtImportService")
@Service("importService")
//使用value作为bean的名字,两种写法
public class TxtImportService implements ImportService {
    @Override
    public void importInfo() {
	System.out.println("TxtImportService");
    }
}
  • 注解《4》事务中用到的注解:

推荐博文:Spring事务配置,声明式事物@Transactional

开启事物注释的控制支持 <tx:annotation-driven>

<!-- 开启事务控制的注解支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

<!-- 配置spring的PlatformTransactionManager,名字为默认值 -->
<bean id="transactionManager"      
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>

事务注解:@Transactional

@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法 将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

(1)虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。

(2)另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

(3)默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。

事务@Transactional的属性

(1)事务隔离级别:

隔离级别是指若干个并发的事务之间的隔离程度。

MYSQL的默认隔离级别为可重复读:REPEATABLE-READ;

ORACLE的默认隔离级别为读已提交:READ COMMITTED;

SQL SERVER的默认隔离级别为读已提交:READ COMMITTED;

TransactionDefinition 接口中定义了五个表示隔离级别的常量:

TransactionDefinition.ISOLATION_DEFAULT;

TransactionDefinition.ISOLATION_READ_COMMITTED;

TransactionDefinition.ISOLATION_READ_UNCOMMITTED;

TransactionDefinition.ISOLATION_REPEATABLE_READ;

TransactionDefinition.ISOLATION_SERIALIZABLE。

对应的@Transactional的属性为isolation :

@Transactional(isolation=Isolation.REPEATABLE_READ)

(2)事物的传播行为

所谓事务的传播行为是指,如果在 开始 当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。 TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
对应的@Transactional的属性为propagation

@Transactional(propagation=Propagation.REQUIRED)

(3)事务超时时间

所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。

 默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。

对应的@Transactional的属性为timeout

@Transactional(timeout=10)

(4)事务只读属性

只读事务用于客户代码只读但不修改数据的情形,只读事务用于特定情景下的优化,默认为读写事务。
“只读事务”并不是一个强制选项,它只是一个“暗示”,提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力。
对应的@Transactional的属性为readOlny

@Transactional(readOnly=true)

(5)事务的回归

默认配置下,spring只有在抛出的异常为运行时 unchecked异常 时才回滚该事务,也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚),而抛出checked异常则不会导致事务回滚。可以明确的配置在抛出那些异常时回滚事务,包括checked异常。也可以明确定义那些异常抛出时不回滚事务。
对应的@Transactional的属性为rollbackFor noRollbackFor

@Transactional(rollbackFor=NullPointerException.class)
  • 注解《4》Spring MVC的注解

(1)@RequestMapping 及常用属性说明

@RequestMapping即可以注解在类上也可以注解到具体的方法上;

  • value属性:value支持统配符以及ANT风格的路径,value={"qian",page*}
@RequestMapping("qian")
@RequestMapping(value="/qian")
@RequestMapping(value = {  
        "",  
        "/page",  
        "page*",  
        "view/*,**/msg"  
 })  
  • param 和  headers 属性:用于限定请求中和请求的消息头中是否含有指定的参数
//请求中必须包含stu参数;
@RequestMapping(value="/handle",params="stu")
//请求中必须包含username参数,age参数,并且age的值为20,参数中不能包含pwd参数
@RequestMapping(value="rq1",params={"username","age=20","!pwd"})

@RequestMapping(value="rq1", headers = "headers = "Content-Type=application/json")
  • produces 和 consumes 属性:分别用于指定返回的内容类型和处理请求提交的内容的类型;

推荐博文:Head中Context-Type讲解

// 返回json数据的字符编码为utf-8,下边的代码可以省略produces属性,因为
// 我们已经使用了注解@responseBody就是返回值是json数据.
@Controller 
@RequestMapping(value = "/pets/{petId}", 
                produces="MediaType.APPLICATION_JSON_VALUE;charset=utf-8") 
@ResponseBody 
public Pet getPet(@PathVariable String petId, Model model) { 
    // implementation omitted 
} 
//方法仅处理request Content-Type为“application/json”类型的请求
@Controller 
@RequestMapping(value = "/pets", consumes="application/json") 
public void addPet(@RequestBody Pet pet, Model model) { 
    // implementation omitted 
} 

(2)@RequestBody 和 @ResponseBody

@RequestBody

用于读取Request请求的body部分的数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到解析方法要返回的对象上; 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

@ResponseBody

该注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走 试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。(也就是说 在使用@RequestMapping后,返回值通常解析为跳转路径。加上@responsebody后,返回结果直接写入HTTP response body中,不会被解析为跳转路径。比如异步请求,希望响应的结果是json数据,那么加上@responsebody 后,就会直接返回json数据。

(1)Spring mvc 处理json请求时,默认使用的是 MappingJackson2HttpMessageConverter ;

<!--引入jackson包-->
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-core</artifactId>
   <version>2.7.0</version>
</dependency>
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.7.0</version>
 </dependency>
 <dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.7.0</version>
 </dependency>

(2)当返回json数据时,防止老版IE出现下载界面;

<mvc:annotation-driven>
        <mvc:message-converters>
            <ref bean="stringHttpMessageConverter"/>
            <ref bean="mappingJackson2HttpMessageConverter"/>
        </mvc:message-converters>
</mvc:annotation-driven>

<bean id="stringHttpMessageConverter"
      class="org.springframework.http.converter.StringHttpMessageConverter"/>

<!--解决IE浏览器json文件下载和json数据中文乱码的问题-->
<bean id="mappingJackson2HttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
            </list>
        </property>
</bean>
// post->String字符串数组
function sendStrArr() {
	var strArr = new Array("Saab","Volvo","BMW");
	var str = "userNamewangwang,age:30";
	$.ajax({
		type:"POST",
		url:"qian/strArrData",
		dataType:"json",
		contentType:"application/json;charset=utf-8",
		data:JSON.stringify(strArr),
		success:function(data){
			
		}
	});
}

@RequestMapping(value="strArrData")
public void receiveString(@RequestBody List<String> strs){
	System.out.println(strs+ ""+strs.size());
}

/*************** post -> java bean *********************/
function userData() {
	var user = {"userName":"zhangsan","age":"20"};
	$.ajax({
		type:"POST",
		url:"qian/userData",
		dataType:"json",
		contentType:"application/json;charset=utf-8",
		data:JSON.stringify(user),
		success:function(data){
			alert(data.age);
		}
	});
}

@RequestMapping(value="userData")
@ResponseBody
public User receiveStringArr(@RequestBody User user){
	System.out.println(user.toString());
	return user;
}

/**************** post -> List<bean> *************************/
function usersData() {
	var userArr = [];
	var user1 = {"userName":"zhangsan","age":"20"};
	var user2 = {"userName":"wangwang","age":"30"};
	userArr.push(user1);
	userArr.push(user2);
	$.ajax({
		type:"POST",
		url:"qian/usersData",
		dataType:"json",
		contentType:"application/json;charset=utf-8",
		data:JSON.stringify(userArr),
		success:function(data){
			alert(data[0].age);
		}
	});
}

@RequestMapping(value="usersData", method=RequestMethod.POST)
@ResponseBody
public List<User> saveUser(@RequestBody List<User> users){
	for(User u :users){
		System.out.println(u.toString());
	}
	return users;
}

关于@RequsetBody可以参考下面三个博文

>> SpringMVC json(1)

>> SpringMVC json(2)

>> SpringMVC json(3)

(3)@PathVariable

将url中相应的部分直接映射到方法对应于@PathVariable注解的变量上;

注意:

(1)spring3 以后,@PathVariable不仅支持Get方法传值,还支持Post方法传值;

(2)对于请求路径的结尾中带有小数点(.)时,Spring会去掉最后一个(.)后面的内容,

GET: http://host:port/program/viewFile/module/201612201231445.pdf

@RequestMapping(value="viewFile/{module}/{filename}",method=RequestMethod.GET)
@RequestMapping(value="viewFile/{module}/{filename:.+}",method=RequestMethod.GET)
public void viewFile(HttpSession session,HttpServletResponse response,@PathVariable String module, @PathVariable String filename){
     //解析后获得到的文件名称为201612201231445并没有或追文件后缀 
}

(3)防止出现空值的问题

(4)@RequestParam

主要用于在SpringMVC后台控制层获取参数,等价操作:request.getParameter("userName")  等价于 @RequestParam(value="userName");

name / value:参数名字,即入参的请求参数名字,如username表示请求的参数区中的名字为username的参数的值将传入;

required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;

defaultValue:默认值,表示如果请求中没有同名参数时的默认值。

具体用户参考一篇不错的文章:@RequestParam的具体使用

 

<form action="/gadget/testRequestParam" method="post">    
    参数inputStr:<input type="text" name="inputStr"> test
    参数intputInt:<input type="text" name="inputInt"> 123
</form>

@RequestMapping("testRequestParam")    
public String filesUpload(@RequestParam String inputStr, HttpServletRequest request){
    System.out.println(inputStr);     
    int inputInt = Integer.valueOf(request.getParameter("inputInt"));  
    System.out.println(inputInt);   
}
output: test
        123

如果用@RequestParam注解的参数是int基本类型,但是required=false,这时如果不传参数值会报错,因为不传值,会赋值为null给int,这个不可以 建议使用包装类型代替基本类型,如使用“Integer”代替“int

@RequestParam VS @RequestBody

@RequestParam 

(1) 常用来处理简单类型的绑定,通过Request.getParameter() 获取的String可直接转换为简单类型的情况( String--> 简单类型的转换操作由ConversionService配置的转换器来完成);因为使用request.getParameter()方式获取参数,所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值;

(2)用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式GET、POST;

@RequestBody

(1)该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。

(2)因为配置有FormHttpMessageConverter,所以也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap<String, String>里

(5)@ModelAttribute

(1)ModelAttribute标注在方法上,在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法;注意:使用 @ModelAttribute(“attributeName”) 标记方法的时候,若未指定atrributeName,则使用返回类型的类名称(首字母小写)作为属性名称;

(2)ModelAttribute标注在方法的参数上,

//UserController.java在方法入参处使用@ModelAttribute
@RequestMapping(value="/model")
public String handleModel(@ModelAttribute("user") User user){
    user.setUserId("1000");
    return "/user/createSuccess";
}

SpringMVC 将请求消息绑定到User对象中,然后再以“user”为键将User对象放到模型中。对于JSP视图来说,SpringMVC会将模型数据转储到ServletRequest的属性列表中(即通过ServletRequest#setAttribute(String name,Object o )保存)。handleModel()返回的逻辑视图名为 /user/createSuccess,对应createSuccess.jsp视图对象,这样createSuccess.jsp就可以使用${user.userName}等方式顺利访问到模型中的数据了。

SpringMVC中@ModelAttribute与@RequestBody的区别:参考

(6)SessionAttribute

推荐一个不错的博文说的很详细:SpringMVC @SessionAttributes 使用详解以及源码分析

 

 

基于物联网技术智慧园林绿化养护管理信息平台 近几年来,随着经济不断的发展,城市面积不断的扩大,城市管理中的园林绿化工作也在这种趋势下不断的发生着深刻改变。管养企业是否按制定的管养计划严格执行?绿化事件整改是否及时到位?绿地面积是否在稳步增长?管养的效果如何?如何客观评价管养企业的管养工作?这些都是我们各级管理者需要面对的问题。   智慧园林绿化养护管理信息平台的开发思路以“考核”为核心,整个信息平台体现出“新、快、高、全、享”五个特点。   智慧园林绿化养护管理信息平台的整个开发理念为:依托五大技术手段(全球卫星定位系统技术、地理信... 阅读详情

相关推荐

DSSP 工具:蛋白质二级结构信息计算与批量处理教程

DSSP(Dictionary of Secondary Structure in Proteins)是一款经典的蛋白质二级结构计算工具,由荷兰癌症研究所(NKI Research)Perrakis 团队维护。它通过分析蛋白质的 PDB 结构文件,能够自动标注每个氨基酸残基的二级结构类型、相对溶剂可及性(暴露面积)等关键信息,为后续的拓扑图绘制、疏水 / 亲水表面分析、二级结构预测模型训练等提供核心数据支持。

good_rrrrr的博客 1835

context:annotation-config 标签 详细解释

我们一般在含有Spring的项目中,可能会看到配置项中包含这个配置节点context:annotation-config,这是一条向Spring容器中注册: AutowiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor、 PersistenceAnnotationBeanPostProcessor、 Required...

明月朗,潇水寒 9817

CANoe UDS $27服务DLL生成实战:从工程配置到算法修改全流程

本文详细介绍了在Vector CANoe中为UDS(统一诊断服务)的$27安全访问服务生成定制化DLL(动态链接库)的全流程。从定位官方参考工程、配置Visual Studio开发环境,到深入解析核心的GenerateKeyEx函数接口,并重点演示了如何修改和实现自定义的种子-密钥安全算法,最终完成DLL的编译、部署与CANoe集成测试,为汽车电子诊断开发提供实战指导。

star5的专栏 534

Spring配置项<context:annotation-config/>解释说明

在基于主机方式配置Spring的配置文件中,你可能会见到这样一条配置,他的作用是式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 RequiredAnnotationBeanPostProc

赶路人儿 1323

macOS 发票查验全攻略:从证书导入到Safari调试

本文详细介绍了在macOS上进行发票查验的全流程,包括证书下载、钥匙串访问导入、Safari浏览器调试等关键步骤。重点解决了验证码不显示等常见问题,提供了证书信任设置和开发者工具使用的实用技巧,帮助用户顺利完成税务发票在线查验。

weixin_29204749的博客 544

ABA分析方法 — 软硬件开发必备的一种分析问题绝佳套路

可能你从很多地方听过这个名词,无论是在软件开发还是硬件领域(比较典型的领域:汽车、消费电子、医疗等行业),ABA验证都是一种快速分析故障的一个方法,第一次听到这个词,当时是不是一脸懵逼,本文就深度带你了解下ABA的分析方法。简要概述就是:怀疑A模块导致系统故障,将B模块替换A模块,故障消失,再将A模块替换回来,故障复现,则说明A模块是导致系统故障的原因其实,ABA分析问题,可能很多人在工作中都或多或少用过这个方法,只是没有这个概念,说明白了就是控制变量和对比验证,没什么高大上的东西。

Eureka1024的博客 7318

<context:annotation-config/>的作用

在传统声明方式中 类似这样的注入IOC容器中 <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/> 1.如果想使用@ Resource 、@ PostConstruct、@ PreDestroy等注解就必须声明CommonAnnotation...

weixin_30687587的博客 366

当KCF遇见卡尔曼滤波:视觉跟随算法的动态优化实战

本文探讨了KCF算法与卡尔曼滤波在视觉跟随算法中的动态优化实践,通过深度融合策略提升目标跟踪的鲁棒性和实时性。特别针对机器人应用场景,详细解析了在Jetson等嵌入式平台上的优化技巧,包括计算图优化、内存访问优化和多线程流水线设计,实现了30FPS@1080p的稳定跟踪性能。

sugar的博客 956

Spring框架中Spring配置文件中context:annotation-config标签说明

<context:annotation-config/>此标签的重要作用就是:   省去系统繁琐的注解标签,加上一个此标签,就可以在此项目程序添加“注解”的功能,使系统识别相应的注解功能!! 详解: <context:annotation-config/>标签的作用是隐式地向Spring容器注册AutowiredAnnotationBeanPostProcesso...

simple_237615452的博客 925

STM32驱动AD2S1210实现旋变解码与角度读取

旋转变压器作为一种耐高温、抗振动的角度传感器,在工业伺服、机器人关节和电动汽车电驱等场景中占据重要地位。其输出信号需要经过专用转换芯片处理才能被MCU高效使用。AD2S1210是一款典型的旋变数字转换器(RDC),内部采用Type II型跟踪环,将模拟SIN/COS信号实时解算为数字角度与速度,降低了处理器负担并提升抗干扰能力。本文基于STM32平台,详细介绍了AD2S1210的硬件接线、SPI通信配置、寄存器初始化流程,以及读取位置数据时的SAMPLE脉冲时序等关键实现。同时总结了常见故障如全FF、角度跳

weixin_34194829的博客 190

2026AI漫剧放心大胆做!小白也能轻松出片(附保姆级教程)

要是在2025,我大概率会劝他再等等,毕竟那时工具还没这么顺手。但到了2026年的今天,我的回答得很干脆:放心去做,绝对没问题。这一年多来,AI漫剧这块的变化真可谓翻天覆地。过去你想拍个像样的短片,哪怕再简陋,也得凑齐拍摄设备、找场地、找演员,后期剪辑更是折磨。但现在,时代变了,AI已经把创作的门槛踏平了。你不需要请演员,也不用操心灯光布景,更不用为剪辑特效烧钱。一个人,一台电脑,花几天时间就能做一部完整的AI漫剧。你只要有有想表达的故事,突发的灵感,剩下的,都能直接交给AI落地。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 419

回顾spring注解

spring注解 @ComponentScan: 包扫描 @Bean: 注册/声明一个组件,并将其交给Spring进行管理 @Configuration 用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。 把一个类作为一个IoC容器

weixin_43868840的博客 180

【WorkBuddy专栏25】如何选择大模型——积分消耗、用途场景、选型决策全指南

【WorkBuddy专栏25】如何选择大模型——积分消耗、用途场景、选型决策全指南

AI人人懂 927

Spring5 14 注解实现AOP&&回顾Mybatis

在 一个类 的 上面 加上 让其 变为切面类。然后 再加一个 让这个 类 在 spring 容器中 注册。在 before、after、around 方法 的上面 加上 对应的 注解。 被 注解的方法有些特殊,因为是 环绕的方法。所以 spring 允许 你有个参数。这个参数的类型是 ,这个东西 叫做 注入点。我们可以通过它 拿到 很多 被代理对象/接口 的 很多信息。 编写 配置文件 进行基础测试...

小哞^同^学的技术博客 284

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Spring--注解回顾

1. Spring--注解回顾 Spring学完了有一段时间了,有时候,看到Spring里面的某些注解时会有点模棱两可的感觉,趁着今天周末,我就来回顾一下Spring相关的注解。 从广义上Spring注解可以分为两类: 用于注册Bean 用于使用Bean 1.1 用于注册Bean的注解 Spring注解开发 假如IOC容器就是一间空屋子,首先这间空屋子啥都没有,我们要吃大餐,我们就要从外部 搬运食材和餐具进来。这里把某一样食材或者某一样餐具搬进空屋子的操作就相当于每个注 册Bean的注解作用类似。注册

天行健 君子以自强不息,地势坤 君子以厚德载物。 599

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Spring-注解回顾

文章目录关于容器关于注入spring的新注解关于配置类:关于AOP关于事务 最近学习springboot时,发现注解的使用还是很重要的,于是在这回顾一下 关于容器 @Component:把资源让 spring 来管理。相当于在 xml 中配置一个 bean。 value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。 @Contro...

NULL_YM 236

Spring注解,记录一下,方便回顾

Spring注解一、扫描注解与自定义扫描规则@ComponentScan扫描注解自定义扫描规则:ComponentScan包含的属性有valueexcludeFilters:不包含什么注解includeFilters:包含什么注解两个的参数都是@Filter注解数组。如:@ComponentScan(value="com.spring02.demo1",excludeFilters={@Filte...

sinat_32143899的博客 179

整理出来的关于Spring的注解,方便记忆回顾

1.和装配bean有关: @Compnent :三个引申 @Controller :表现层(web) @Service :业务层 @Repository :持久层dao() 2.注入相关 @Autowired @Qualifier(value="?") @Resource(name="?") @Value:自动注入属性值,通过${}获取 3.生命周期和范围: @PostConstruct:初始方法 @PreDestroy:销毁方法 @Scope:作用范围,singleton,protype 4.配

lq34567890的博客 369

【Spring学习27】回顾总结Spring常用注解

前面已经多次用到了注解,如自动装配、扫描,bean初始化及销毁回调等 现在汇总并回顾一下:1、 @Autowired 注解要让@Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。<!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -

程序老兵的博客 2060

Spring回顾学习(二)Spring常用注解的一些理解

1.Spring配置数据源 1.1数据源(连接池)的作用 数据源(连接池)是提高程序性能的,事先实例化数据源并且初始化部分连接资源,这样在使用连接资源时就可以直接从数据源中获取,使用完毕后将连接的资源归还给数据源(如果不记得归还那么容易出现一个bug,就是连接池的连接数量到达了上限,那么在下一次请求中如果需要连接池对象那么就会出现一个超时的bug,尤其是在前后端交互数据时一不小心忘记释放资源,最容...

lzh_2_4的博客 150

Spring学习回顾(六)bean的注解配置

bean的注解配置 前面通过示例已经看到,从Spring的2.5版本之后不但引入了p命名空间来简化xml,而且还开始支持注解的配置方式,几乎消灭了配置文件。需要实例化的类不需要再在配置文件中一个一个的进行配置,而是Spring通过扫描指定的位置,来自动的配置管理bean。接下来创建以下类,来感受注解配置方式的好处。 Person类:具有自我介绍方法 package com.me.spring; ...

weixin_42448279的博客 281

10.Spring AOP半注解和全注解模式回顾

<bean id="logUtils" class="com.lagou.edu.utils.LogUtils"></bean> <aop:config> <aop:aspect id="logAspect" ref="logUtils"> </aop:aspect> </aop:config> 修改成以下注解 &lt;!&ndash;切入点锁定我们感兴趣的方法,使用aspectj语法...

moshubai的博客 227

Spring注解驱动之注册组件(spring的再回顾)

一. 组件注册 1. 给容器中注册组件 xml方式 创建一个实体类(构造方法等省略) public class Person { private String name; private Integer age; } resources资源目录下创建xml文件 利用bean标签注册一个组件 得到id,方便从容器中获取该bean 使用property进行属性赋值 <bean id="person" class="com.lcy.bean.Person">

TxbLcy的博客 755

【Spring源码解析】-- Java注解知识回顾(一)

前言 在学习spring注解驱动开发之前,我们先来回顾一下Java的注解相关的知识。 一、注解的定义 直接看代码: /*自定义注解@Book*/ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented public @interface Book { String name() default...

小虎的博客 306

Spring6(八)注解的回顾学习使用

无

m0_58565716的博客 131

Spring(注解+依赖注入+无配置注解+AOP)适合回顾♥♥

1.注解的使用 @Autowired自动注入 2.依赖注入 3.无配置注解

cout_s的博客 331
上一篇: Jdk6 7 9 流关闭的新姿势
下一篇: TXT 数据文件批量导入DB
Coder-Qian
博客等级 码龄11年 63粉丝 73原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值