Spring注解介绍
- 格式:docx
- 大小:38.68 KB
- 文档页数:6
Spring中三个注解@PathVariable、@Param和@RequestParam间的区别@PathVariable代码⽰例:@ResponseBody@RequestMapping("/user/{uid}")public User getUserById(@PathVariable("uid") Long uid) {}特点:1) 应⽤在Controller层2) @PathVariable是spring3.0的⼀个新功能:可接收请求路径中占位符的值,通过 @PathVariable 可以将URL中占位符参数{uid}绑定到处理器类的⽅法形参uid中 —— @PathVariable(“uid“)3) 请求路径中占位符的名字可与⽅法参数名不⼀样@RequestParam代码⽰例:@ResponseBody@RequestMapping(value = "/user/get", method = RequestMethod.POST)public List<User> getUserList(@RequestParam("uid") Integer id, @RequestParam("uname") String name) {}特点:1) @RequestParam主要应⽤在Controller层2) 前端提交的form表单数据中的属性名和⽅法中的参数名不⼀致时,springMVC就⽆法⾃动封装参数,所以需要 @RequestParam("前端所传属性名")来指定前端提交的表单的属性的名称3) 前端提交的form表单数据中的属性名和⽅法中的参数名⼀致时,可以不使⽤此注解@Param代码⽰例:@Select("select * from user where uid = #{uid} and uname = #{uname}")List<User> getUserList(@Param("uid") Integer id, @Param("uname") String name);特点:1) @Param主要应⽤在Dao层2) 注解中的sql语句有多个条件参数,且和⽅法中的参数名称不⼀致,此时可以使⽤@Param注解3) 只有⼀个参数时,可以不使⽤注解(不过还是建议使⽤= =)4) 参数的顺序⽆关参考:https:///pengfudian1991/article/details/96336898https:///qq_36268103/article/details/109994954。
spring注解@Service注解的使⽤解析@Service注解的使⽤要说明@Service注解的使⽤,就得说⼀下我们经常在spring配置⽂件applicationContext.xml中看到如下图中的配置:<!-- 采⽤扫描 + 注解的⽅式进⾏开发可以提⾼开发效率,后期维护变的困难了,可读性变差了 --><context:component-scan base-package="com.study.persistent" />在applicationContext.xml配置⽂件中加上这⼀⾏以后,将⾃动扫描指定路径下的包,如果⼀个类带了@Service注解,将⾃动注册到Spring容器,不需要再在applicationContext.xml配置⽂件中定义bean了,类似的还包括@Component、@Repository、@Controller。
如这个类:@Service("courseDAO")@Scope("prototype")public class CourseDAOImpl extends HibernateDaoSupport implements CourseDAO{......}其作⽤就相当于在applicationContext.xml配置⽂件⾥配置如下信息:<bean id="courseDAO"class="com.study.persistent.CourseDAOImpl" scope="prototype">......</bean>@Service("serviceName")注解相当于applicationContext.xml配置⽂件中配置的<bean id="serviceName">,表⽰给当前类命名⼀个别名,⽅便注⼊到其他需要⽤到的类中。
Spring注解【⾮单例】花了⾄少⼀整天的时间解决了这个问题,必须记录这个纠结的过程,问题不可怕,思路很绕弯。
为了能说清楚⾃⼰的问题,我都⽤例⼦来模拟。
我有⼀个类MyThread是这样的:1 @Service2public class MyThread extends Thread {3 @Autowired4 MyService myService;5 ......6 }在主线程中有这样⼀个调⽤:1 @Autowired2 MyThread myThread;3 ......4public void invoke{5if(condition){6 myThread.start();7 }8 }9 ......我的invoke存在⼀个循环调⽤,此时遇到了第⼀个问题!问题⼀:抛出ng.IllegalThreadStateException。
问题⼀的解决:1//@Autowired2//MyThread myThread;3 ......4public void invoke {5if(condition){6 //myThread.start();6 MyThread myThread = new MyThread();7 myThread.start();8 }9 }引发的新的问题!问题⼆:我⽤了Spring注解,⽤new的话⽆法⽤注解实现注⼊,所以myThread中的myService对象抛出空指针。
问题⼆的解决:放弃了MyThread类,新写了⼀个类,开始绕弯。
1 @Service2public class MyRunable implements Runnable {3 @Autowired4 MyService myService;5 ......6 }相应的,修改主线程中的调⽤。
1//@Autowired2//MyThread myThread;3 @Autowired4 MyRunnable myRunnable;5 ......6public void invoke{7if(condition){8//MyThread myThread = new MyThread();9//myThread.start();10 Thread t = new Thread(myRunnable);11 t.start();12 }13 }14 ......⼜遇到了新的问题!我需要对myRunnable线程命名。
【SpringFramework】Spring⼊门教程(三)使⽤注解配置本⽂主要介绍四个⽅⾯:(1) 注解版本IOC和DI(2) Spring纯注解(3) Spring测试(4) SpringJDBC - Spring对数据库的操作使⽤注解配置Spring⼊门说在前⾯学习基于注解的IoC配置,⼤家脑海⾥⾸先得有⼀个认知,即注解配置和xml配置要实现的功能都是⼀样的,都是要降低模块间的耦合度。
仅仅只是配置的形式不⼀样。
关于实际的开发中到底使⽤xml还是注解,每家公司有着不同的使⽤习惯。
所以这两种配置⽅式我们都需要掌握。
基于注解配置的⽅式也已经逐渐代替xml配置。
所以我们必须要掌握使⽤注解的⽅式配置Spring。
配置步骤注意:如果使⽤Eclipse需要先安装了STS插件,或者使⽤STS开发⼯具创建项⽬。
本⽂使⽤IDEA进⾏演⽰。
1.2.1. 第⼀步:拷贝必备jar包到⼯程的lib⽬录。
注意:在基于注解的配置中,我们还要多拷贝⼀个aop的jar包。
如下图:1.2.2. 第⼆步:在类的根路径下创建⼀个任意名称的xml⽂件(不能是中⽂)注意:基于注解整合时,Spring配置⽂件导⼊约束时需要多导⼊⼀个context命名空间下的约束。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd/schema/context/schema/context/spring-context.xsd"></beans>1.2.3. 第⼆步:创建⼀个服务类创建⼀个测试的服务类,并且加⼊使⽤@Component注解,声明该类允许注⼊到Spring容器package org.cjw.service;import ponent;/*使⽤注解配置时,需要将Spring框架启动就创建对象的类表⽰为组件类表⽰组件类使⽤@Component注解*/@Componentpublic class CustomerService {public void save() {System.out.println("-保存数据-");}}1.2.4. 第四步在spring的配置⽂件加⼊扫描注解<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd/schema/context/schema/context/spring-context.xsd"><!-- 声明扫描包及其⼦包的类,如果发现有组件注解的类,就创建对象并加⼊到容器中去 --><context:component-scan base-package="org.cjw" /></beans>1.2.5. 第五步:测试调⽤代码package org.cjw.test;import org.cjw.service.CustomerService;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class CustomerServiceTest {@Testpublic void testSave() {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");CustomerService customerService = context.getBean(CustomerService.class);customerService.save();}}--测试结果,如果可以调⽤服务⽅法,测试成功。
Spring中的@Valid和@Validated注解你⽤对了吗1.概述本⽂我们将重点介绍Spring中和注解的区别。
验证⽤户输⼊是否正确是我们应⽤程序中的常见功能。
Spring提供了@Valid和@Validated两个注解来实现验证功能,下⾯我们来详细介绍它们。
2. @Valid和@Validate注解在Spring中,我们使⽤@Valid 注解进⾏⽅法级别验证,同时还能⽤它来标记成员属性以进⾏验证。
但是,此注释不⽀持分组验证。
@Validated则⽀持分组验证。
3.例⼦让我们考虑⼀个使⽤Spring Boot开发的简单⽤户注册表单。
⾸先,我们只有名称和密码属性:public class UserAccount {@NotNull@Size(min = 4, max = 15)private String password;@NotBlankprivate String name;// standard constructors / setters / getters / toString}接下来,让我们看⼀下控制器。
在这⾥,我们将使⽤带有@Valid批注的saveBasicInfo⽅法来验证⽤户输⼊:@RequestMapping(value = "/saveBasicInfo", method = RequestMethod.POST)public String saveBasicInfo(@Valid @ModelAttribute("useraccount") UserAccount useraccount,BindingResult result,ModelMap model) {if (result.hasErrors()) {return "error";}return "success";}现在让我们测试⼀下这个⽅法:@Testpublic void givenSaveBasicInfo_whenCorrectInput`thenSuccess() throws Exception {this.mockMvc.perform(MockMvcRequestBuilders.post("/saveBasicInfo").accept(MediaType.TEXT_HTML).param("name", "test123").param("password", "pass")).andExpect(view().name("success")).andExpect(status().isOk()).andDo(print());}在确认测试成功运⾏之后,现在让我们扩展功能。
Spring注解@component、@service、@Autowired等作⽤与区别1、@Service⽤于标注业务层组件2、@Controller⽤于标注控制层组件(如struts中的action)3、@Repository⽤于标注数据访问组件,即DAO组件.4、@Component泛指组件,当组件不好归类的时候,我们可以使⽤这个注解进⾏标注。
5、@Autowired与@Resource的区别: @Autowired由Spring提供,只按照byType注⼊,默认情况下必须要求依赖对象存在,如果要允许null值,可以设置它的required属性为false。
如果想使⽤名称装配可以结合@Qualifier注解进⾏使⽤。
public class UserService {@Autowired@Qualifier(name="userDao1")private UserDao userDao;} @Resource由J2EE提供,默认按照byName⾃动注⼊,Spring将@Resource注解的name属性解析为bean的名字,type属性则解析为bean的类型。
所以如果使⽤name属性,则使⽤byName的⾃动注⼊策略,⽽使⽤type属性则使⽤byType⾃动注⼊策略。
①如果同时指定了name和type,则从Spring上下⽂中找到唯⼀匹配的bean进⾏装配,找不到则抛出异常。
②如果指定了name,则从上下⽂中查找名称(id)匹配的bean进⾏装配,找不到则抛出异常。
③如果指定了type,则从上下⽂中找到类似匹配的唯⼀bean进⾏装配,找不到或是找到多个,都会抛出异常。
④如果既没有指定name,⼜没有指定type,则⾃动按照byName⽅式进⾏装配;如果没有匹配,则回退为⼀个原始类型进⾏匹配,如果匹配则⾃动装配。
总结:@Resource的作⽤相当于@Autowired,只不过@Autowired按byType⾃动注⼊。
Spring常⽤的⼀些注解说明@Configuration从Spring3.0,@Configuration⽤于定义配置类,可替换xml配置⽂件,被注解的类内部包含有⼀个或多个被@Bean注解的⽅法。
这些⽅法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进⾏扫描,并⽤于构建bean定义。
@Bean@Bean注解⽤于告诉⽅法,产⽣⼀个Bean对象,然后这个Bean对象交给Spring管理。
产⽣这个Bean对象的⽅法Spring只会调⽤⼀次,随后这个Spring将会将这个Bean对象放在⾃⼰的IOC容器中。
SpringIOC 容器管理⼀个或者多个bean,这些bean都需要在@Configuration注解下进⾏创建,在⼀个⽅法上使⽤@Bean注解就表明这个⽅法需要交给Spring进⾏管理。
@Autowired、@Resource@Resource和@Autowired注解都是⽤来实现依赖注⼊的。
只是@AutoWried按by type⾃动注⼊,⽽@Resource默认按byName⾃动注⼊。
♣ @Autowired@Autowired具有强契约特征,其所标注的属性或参数必须是可装配的。
如果没有Bean可以装配到@Autowired所标注的属性或参数中,⾃动装配就会失败,抛出NoSuchBeanDefinitionException.@Autowired可以对类成员变量、⽅法及构造函数进⾏标注,让 spring 完成 bean ⾃动装配的⼯作。
@Autowired 默认是按照类去匹配,配合 @Qualifier 指定按照名称去装配 bean。
♣ @Resource@Resource是JDK提供的注解,有两个重要属性,分别是name和type。
@Resource依赖注⼊时查找bean的规则既不指定name属性,也不指定type属性,则⾃动按byName⽅式进⾏查找。
Spring注解之@Primary注解 当⼀个接⼝有多个不同实现类时,使⽤注解@Autowired时会报org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [xxxx] is defined: expected single matching bean but found 2:xxx1,xxx2异常信息,意思是Spring 发现两个类型相同的bean,⽆法根据类型选择装配哪⼀个。
这时候就可以使⽤@Primary注解设置默认bean,使得项⽬启动时只装配其中⼀种bean。
@Primary:在众多相同的Bean中,优先使⽤@Primary注解的Bean。
⽅案1-@Qualifier @Qualifier注解⽤于细粒度地根据bean名称选择bean候选者,是遇到多个相同类型bean时⽐较常⽤的解决⽅案。
注解@Autowired 默认是根据类型来⾃动注⼊bean,结合 @Qualifier使⽤时,⾃动注⼊的策略就从 byType 转变成 byName 了。
⽅案2-@Primary @Primary可以理解为,装配bean的时候优先选择使⽤@Primary注解的Bean。
相同类型的bean不可以同时设置多个@Primary注解。
内部实质是设置BeanDefinition的primary属性。
@Primary案例分析 以在某个相同类型的bean上添加注解@Primary为案例进⾏分析。
测试⽤例中,Shape接⼝类有三个实现类。
/*** 定义bean接⼝*/public interface Shape {void draw();}=========== 我是分割线 =============@Primary@Servicepublic class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Inside Rectangle::draw() method.");}}=========== 我是分割线 =============@Servicepublic class Square implements Shape {@Overridepublic void draw() {System.out.println("Inside Square::draw() method.");}}=========== 我是分割线 =============@Servicepublic class Circle implements Shape {@Overridepublic void draw() {System.out.println("Inside Circle::draw() method.");}}因为实现类 Rectangle 被注解@Primary修饰,所以它将优先被装配到接⼝类 Shape。
Spring四⼤注解四⼤注解的作⽤:以下四个注解能快速的将bean加载到ioc容器当中,不需要和以前⼀样,再xml的beans中创建bean的形式来加⼊。
1. @Repository:该注解主要针对于数据访问层的(Dao,持久化层)2. @Service:该注解主要针对于业务逻辑层(service层)3. @Controller:该注解主要针对于控制器层(servlet层,Controller层)4. @Component:该注解不属于任何层,当该类不知道属于以上三类的那⼀类时可以使⽤该注解。
以上都是推荐使⽤,这样更加显⽽易见每个类的功能,当然也可以随便添加作⽤还是存在的。
加⼊到ioc容器的步骤1. 创建类,再每个类上添加对应的注解2. 导⼊context命名空间,扫描其注解所再的包再ioc容器当中。
3. 如果⼯⼚是导⼊jar包的形式,那么⼀定要导⼊spring aop 的包,aop 包⽀持添加注解形式4. 需要得到bean时,bean的ID就是注解类的⾸字母⼩写。
项⽬架构maven<dependencies><!-- spring 核⼼包 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.0.RELEASE</version></dependency><!-- ⽇志包--><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1.1</version></dependency><!-- 单元测试包--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.8</version></dependency></dependencies>xml<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="/schema/context"<!-- 扫描com.stone.dome包下的所有注解 --><context:component-scan base-package="com.stone.dome"/></beans>类@Repositorypublic class BookDao{private int a = 15 ;public int getA(){return a;}public void setA(int a){this.a = a;}}测试public class SpringIocDome2{private ApplicationContext ioc =new ClassPathXmlApplicationContext("applicationContext.xml");@Testpublic void test1(){BookDao bookDao = ioc.getBean("bookDao", BookDao.class);int a = bookDao.getA();System.out.println(a);}}运⾏结果使⽤注解的模式加⼊bean到ioc容器的注意点:1. bean的id就是类的⾸字母⼩写2. bean的作⽤域默认为单例 singleton。
详解Spring缓存注解@Cacheable,@CachePut,@CacheEvict使⽤注释介绍@Cacheable@Cacheable 的作⽤主要针对⽅法配置,能够根据⽅法的请求参数对其结果进⾏缓存@Cacheable 作⽤和配置⽅法参数解释examplevalue 缓存的名称,在 spring 配置⽂件中定义,必须指定⾄少⼀个例如:@Cacheable(value=”mycache”)@Cacheable(value={”cache1”,”cache2”}key 缓存的 key,可以为空,如果指定要按照SpEL 表达式编写,如果不指定,则缺省按照⽅法的所有参数进⾏组合@Cacheable(value=”testcache”,key=”#userName”)condition 缓存的条件,可以为空,使⽤ SpEL 编写,返回 true或者 false,只有为 true 才进⾏缓存@Cacheable(value=”testcache”,condition=”#userName.length()>2”)实例@Cacheable(value=”accountCache”),这个注释的意思是,当调⽤这个⽅法的时候,会从⼀个名叫 accountCache 的缓存中查询,如果没有,则执⾏实际的⽅法(即查询数据库),并将执⾏的结果存⼊缓存中,否则返回缓存中的对象。
这⾥的缓存中的 key 就是参数 userName,value 就是Account 对象。
“accountCache”缓存是在 spring*.xml 中定义的名称。
@Cacheable(value="accountCache")// 使⽤了⼀个缓存名叫 accountCachepublic Account getAccountByName(String userName) {// ⽅法内部实现不考虑缓存逻辑,直接实现业务System.out.println("real query account."+userName);return getFromDB(userName);}@CachePut@CachePut 的作⽤主要针对⽅法配置,能够根据⽅法的请求参数对其结果进⾏缓存,和 @Cacheable 不同的是,它每次都会触发真实⽅法的调⽤@CachePut 作⽤和配置⽅法参数解释examplevalue 缓存的名称,在spring 配置⽂件中定义,必须指定⾄少⼀个@CachePut(value=”my cache”)key 缓存的key,可以为空,如果指定要按照SpEL 表达式编写,如果不指定,则缺省按照⽅法的所有参数进⾏组合@CachePut(value=”testcache”,key=”#userName”)缓存的条件,可以为空,使⽤condition SpEL 编写,返回true 或者false,只有为 true 才进⾏缓存@CachePut(value=”testcache”,condition=”#userName.length()>2”)参数解释example实例@CachePut 注释,这个注释可以确保⽅法被执⾏,同时⽅法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。
Spring注解使⽤场景启始版本模式注解@Repository数据仓储模式注解Spring Framework 2.0 @Component通⽤组件模式注解Spring Framework 2.5 @Service服务模式注解Spring Framework 2.5 @Controller Web控制器模式注解Spring Framework 2.5 @Configuration配置类模式注解Spring Framework 3.0装配注解@ImportResource替换XML元素<import>Spring Framework 2.5 @Import限定@Autowired依赖注⼊范围(导⼊对应的 @Configuration 标识类)Spring Framework 3.0 @ComponentScan扫描制定package下标注Spring模式注解的类Spring Framework 3.1依赖注⼊注解@Autowired Bean依赖注⼊,⽀持多种依赖查找⽅式Spring Framework 2.5 @Qualifier细粒度的@Autowired依赖查找⽅式Spring Framework 2.5 @Resource [JAVA注解]Bean依赖注⼊,仅⽀持名称依赖查找⽅式Spring Framework 2.5 Bean定义注解@Bean替换XML元素<bean/>Spring Framework 3.0 @DependsOn替换XML属性<bean depends-on="..."/>Spring Framework 3.0 @Lazy替代XML属性<bean lazy-init="true|false"/>Spring Framework 3.0 @Primary替换XML属性<bean primary="true|false"/>Spring Framework 3.0 @Role替换XML属性<bean role="..."/>Spring Framework 3.1 @Lookup替代XML属性<bean lookup-method="..."/>Spring Framework 4.1条件装配注解@Profile配置化条件装配Spring Framework 3.1 @Conditional编程条件装配Spring Framework 4.0配置属性注解@PropertySource配置属性抽象PropertySource注解Spring Framework 3.1 @PropertySources@PropertySource集合注解(实现 JAVA 8 @Repeatable相似的功能)Spring Framework 4.0⽣命周期回调注解@PostConstruct替换XML元素<bean init-method="..."/>或InitializingBean Spring Framework 2.5 @PreDestory替换XML元素<bean destory-method="..."/>或 DisposableBean Spring Framework 2.5注解属性注解@AliasFor别名注解属性,实现复⽤的⽬的Spring Framework 4.2性能注解@Indexed提升Spring模式注解的扫描效率(编译时会在classPath下⽣成 META-INF/ponents⽂件)Spring Framework 5.0Spring核⼼注解Spring核⼼注解归类如下:。
SpringBoot注解解析⼤全(⾮常全哦!)使⽤注解的优势:1.采⽤纯java代码,不在需要配置繁杂的xml⽂件2.在配置中也可享受⾯向对象带来的好处3.类型安全对重构可以提供良好的⽀持4.减少复杂配置⽂件的同时亦能享受到springIoC容器提供的功能⼀、注解详解(配备了完善的释义)------(可采⽤ctrl+F 来进⾏搜索哦~~~~也可以收藏⽹页这样以后就不⽤往复查询了哦)@SpringBootApplication:申明让spring boot⾃动给程序进⾏必要的配置,这个配置等同于:@Configuration ,@EnableAutoConfiguration 和 @ComponentScan 三个配置。
@ResponseBody:表⽰该⽅法的返回结果直接写⼊HTTP response body中,⼀般在异步获取数据时使⽤,⽤于构建RESTful的api。
在使⽤@RequestMapping后,返回值通常解析为跳转路径,加上@esponsebody后返回结果不会被解析为跳转路径,⽽是直接写⼊HTTP response body中。
⽐如异步获取json数据,加上@Responsebody后,会直接返回json数据。
该注解⼀般会配合@RequestMapping⼀起使⽤。
@Controller:⽤于定义控制器类,在spring项⽬中由控制器负责将⽤户发来的URL请求转发到对应的服务接⼝(service层),⼀般这个注解在类中,通常⽅法需要配合注解@RequestMapping。
@RestController:⽤于标注控制层组件(如struts中的action),@ResponseBody和@Controller的合集。
@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。
@EnableAutoConfiguration:SpringBoot⾃动配置(auto-configuration):尝试根据你添加的jar依赖⾃动配置你的Spring应⽤。
spring boot核心注解
Spring Boot核心注解:
1. @SpringBootApplication:这是一个复合注解,包括@EnableAutoConfiguration、@ComponentScan和
@Configuration等。
它可以用来标注在某个类上,告诉Spring Boot引导类已经准备好了,可以开始以此类为中心进行自动配置、组件扫描和Bean定义加载等工作。
2. @EnableAutoConfiguration:使用这个注解的类,会触发自动配置,就是自动配置文件会被加载,自动配置类会被触发。
3. @ComponentScan:标注在某个类上,用来开启组件扫描,自动发现并装配bean实例到Spring容器中。
4. @Configuration:这是一个配置类,用来替代XML 配置文件,将一些初始化bean定义加载到Spring容器中。
5. @Bean:用来标注在某个方法上,表示此方法返回的结果是一个Bean,可以被Spring容器托管。
Spring的注解一、 spring注解1、@Autowired注入注解@Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装工作。
@Autowired的标注位置不同,它们都会在Spring在初始化这个bean时,自动装配这个属性。
@Autowired是根据类型进行自动装配的。
例如,如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常。
如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。
我们可以使用@Qualifier配合@Autowired来解决这些问题。
1.public class TestController {2.3.@Autowired4.@Qualifier(“u serDao”)5.Private UserService userService;6.7.@RequestMapping("/showView")8.public ModelAndView showView(){9.ModelAndView modelAndView = new ModelAndView();10.modelAndView.setViewName("viewName");11.modelAndView.addObject("属性名称","属性值");12.return modelAndView;13.}14.}2、@Resource注入注解JSR-250标准注解,推荐使用它来代替Spring专有的@Autowired注解。
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource 默认按byName自动注入罢了。
详解springmvc常⽤5种注解⼀、组件型注解:1、@Component 在类定义之前添加@Component注解,他会被spring容器识别,并转为bean。
2、@Repository 对Dao实现类进⾏注解 (特殊的@Component)3、@Service ⽤于对业务逻辑层进⾏注解, (特殊的@Component)4、@Controller ⽤于控制层注解, (特殊的@Component)以上四种注解都是注解在类上的,被注解的类将被spring初始话为⼀个bean,然后统⼀管理。
⼆、请求和参数型注解:1、@RequestMapping:⽤于处理请求地址映射,可以作⽤于类和⽅法上。
●value:定义request请求的映射地址●method:定义地request址请求的⽅式,包括【GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.】默认接受get请求,如果请求⽅式和定义的⽅式不⼀样则请求⽆法成功。
●params:定义request请求中必须包含的参数值。
●headers:定义request请求中必须包含某些指定的请求头,如:RequestMapping(value = "/something", headers = "content-type=text/*")说明请求中必须要包含"text/html", "text/plain"这中类型的Content-type头,才是⼀个匹配的请求。
●consumes:定义请求提交内容的类型。
●produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回@RequestMapping(value="/requestTest.do",params = {"name=sdf"},headers = {"Accept-Encoding=gzip, deflate, br"},method = RequestMethod.GET) public String getIndex(){System.out.println("请求成功");return "index";}上⾯代码表⽰请求的⽅式为GET请求,请求参数必须包含name=sdf这⼀参数,然后请求头中必须有 Accept-Encoding=gzip, deflate, br这个类型头。
3个SpringBoot核⼼注解,你知道⼏个?Spring Boot 核⼼注解讲解Spring Boot 最⼤的特点是⽆需 XML 配置⽂件,能⾃动扫描包路径装载并注⼊对象,并能做到根据 classpath 下的 jar 包⾃动配置。
所以 Spring Boot 最核⼼的 3 个注解就是:1、@Configurationorg.springframework.context.annotation.Configuration这是 Spring 3.0 添加的⼀个注解,⽤来代替 applicationContext.xml 配置⽂件,所有这个配置⽂件⾥⾯能做到的事情都可以通过这个注解所在类来进⾏注册。
下⾯⼏个相关注解也是⾮常重要的!@Bean⽤来代替 XML 配置⽂件⾥⾯的 <bean ...> 配置。
@ImportResource如果有些通过类的注册⽅式配置不了的,可以通过这个注解引⼊额外的 XML 配置⽂件,有些⽼的配置⽂件⽆法通过 @Configuration ⽅式配置的⾮常管⽤。
@Import⽤来引⼊额外的⼀个或者多个 @Configuration 修饰的配置⽂件类。
@SpringBootConfiguration这个注解就是 @Configuration 注解的变体,只是⽤来修饰是 Spring Boot 配置⽽已,或者可利于 Spring Boot 后续的扩展,源码如下。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { }2、@ComponentScanponentScan这是 Spring 3.1 添加的⼀个注解,⽤来代替配置⽂件中的 component-scan 配置,开启组件扫描,即⾃动扫描包路径下的 @Component 注解进⾏注册 bean 实例到 context 中。
Spring中的注解@Autowired实现过程全解(@Autowired背后的故事)现在⾯试,基本上都是⾯试造⽕箭 ,⼯作拧螺丝 。
⽽且是喜欢问⼀些 Spring 相关的知识点,⽐如之间的区别。
魔⾼⼀丈,道⾼⼀尺。
很快不少程序员学会了背诵⾯试题,那我反过来问“Spring 中的注解 @Autowired是如何实现的?”,“说说 @Autowired 的实现原理?”等等,背诵⾯试题的就露馅了。
基于此,今天我们来说⼀说 @Autowired 背后的故事!前⾔使⽤ Spring 开发时,进⾏配置主要有两种⽅式,⼀是 xml 的⽅式,⼆是 Java config 的⽅式。
Spring 技术⾃⾝也在不断的发展和改变,从当前的⽕热程度来看,Java config 的应⽤是越来越⼴泛了,在使⽤ Java config 的过程当中,我们不可避免的会有各种各样的注解打交道,其中,我们使⽤最多的注解应该就是 @Autowired 注解了。
这个注解的功能就是为我们注⼊⼀个定义好的 bean。
那么,这个注解除了我们常⽤的属性注⼊⽅式之外还有哪些使⽤⽅式呢?它在代码层⾯⼜是怎么实现的呢?这是本篇⽂章着重想讨论的问题。
@Autowired 注解⽤法在分析这个注解的实现原理之前,我们不妨先来回顾⼀下 @Autowired 注解的⽤法。
将 @Autowired 注解应⽤于构造函数,如以下⽰例所⽰`public class MovieRecommender {``private final CustomerPreferenceDao customerPreferenceDao;``@Autowired``public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {``this.customerPreferenceDao = customerPreferenceDao;``}``// ...``}`将 @Autowired 注释应⽤于 setter ⽅法`public class SimpleMovieLister {``private MovieFinder movieFinder;``@Autowired``public void setMovieFinder(MovieFinder movieFinder) {``this.movieFinder = movieFinder;``}``// ...``}`将 @Autowired 注释应⽤于具有任意名称和多个参数的⽅法`public class MovieRecommender {``private MovieCatalog movieCatalog;``private CustomerPreferenceDao customerPreferenceDao;``@Autowired``public void prepare(MovieCatalog movieCatalog,``CustomerPreferenceDao customerPreferenceDao) {``this.movieCatalog = movieCatalog;``this.customerPreferenceDao = customerPreferenceDao;``}``// ...``}`您也可以将 @Autowired 应⽤于字段,或者将其与构造函数混合,如以下⽰例所⽰`public class MovieRecommender {``private final CustomerPreferenceDao customerPreferenceDao;``@Autowired``private MovieCatalog movieCatalog;``@Autowired``public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {``this.customerPreferenceDao = customerPreferenceDao;``}``// ...``}`直接应⽤于字段是我们使⽤的最多的⼀种⽅式,但是使⽤构造⽅法注⼊从代码层⾯却是更加好的,具体原因我就不细说了,有不懂的可以留⾔区评论。
Spring系列之Spring常⽤注解总结Spring系列之Spring常⽤注解总结传统的Spring做法是使⽤.xml⽂件来对bean进⾏注⼊或者是配置aop、事物,这么做有两个缺点:1、如果所有的内容都配置在.xml⽂件中,那么.xml⽂件将会⼗分庞⼤;如果按需求分开.xml⽂件,那么.xml⽂件⼜会⾮常多。
总之这将导致配置⽂件的可读性与可维护性变得很低。
2、在开发中在.java⽂件和.xml⽂件之间不断切换,是⼀件⿇烦的事,同时这种思维上的不连贯也会降低开发的效率。
为了解决这两个问题,Spring引⼊了注解,通过"@XXX"的⽅式,让注解与Java Bean紧密结合,既⼤⼤减少了配置⽂件的体积,⼜增加了Java Bean的可读性与内聚性。
不使⽤注解:先看⼀个不使⽤注解的Spring⽰例,在这个⽰例的基础上,改成注解版本的,这样也能看出使⽤与不使⽤注解之间的区别,先定义⼀个⽼虎:package com.spring.model;public class Tiger {private String tigerName="TigerKing";public String toString(){return "TigerName:"+tigerName;}}再定义⼀个猴⼦:package com.spring.model;public class Monkey {private String monkeyName = "MonkeyKing";public String toString(){return "MonkeyName:" + monkeyName;}}定义⼀个动物园:package com.spring.model;public class Zoo {private Tiger tiger;private Monkey monkey;public Tiger getTiger() {return tiger;}public void setTiger(Tiger tiger) {this.tiger = tiger;}public Monkey getMonkey() {return monkey;}public void setMonkey(Monkey monkey) {this.monkey = monkey;}public String toString(){return tiger + "\n" + monkey;}}spring的配置⽂件这么写:<?xml version="1.0" encoding="UTF-8"?><beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:p="/schema/p"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd/schema/context/schema/context/spring-context-3.0.xsd"><bean id="zoo" class="com.spring.model.Zoo"><property name="tiger" ref="tiger"/><property name="monkey" ref="monkey"/></bean><bean id="tiger" class="com.spring.model.Tiger"/><bean id="monkey" class="com.spring.model.Monkey"/></beans>测试⽅法:public class TestAnnotation {/*** 不使⽤注解*/@Testpublic void test(){//读取配置⽂件ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext2.xml");Zoo zoo=(Zoo) ctx.getBean("zoo");System.out.println(zoo.toString());}}都很熟悉,权当复习⼀遍了。
spring参数校验注解在写⼀些controller协议的时候,有些时候从前端传过来的参数较多,好的办法是定义⼀个实体类来封装请求参数,但是⽤实体类封装参数后,⽆法对参数值进⾏校验,可以使⽤spring的@Validated 结合java validation、hibernate validation注解进⾏校验。
1.@validated 注解@Validated is org.springframework.validation.annotation.Validated.复制代码@RequestMapping(value = "/regist", method = {RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic Object hualalaRegist(@Validated HualalaRegistVO registVO, BindingResult bindingResult,HttpServletRequest request) throws Exception {if(bindingResult.hasErrors())return new ResultBean<>(HttpStatus.SC_BAD_REQUEST,"请求参数错误",null);...}复制代码增加@Validated 注解后,表⽰需要对其中的参数进⾏校验。
2.java validation 注解复制代码JSR提供的校验注解:@Null 被注释的元素必须为 null@NotNull 被注释的元素必须不为 null@AssertTrue 被注释的元素必须为 true@AssertFalse 被注释的元素必须为 false@Min(value) 被注释的元素必须是⼀个数字,其值必须⼤于等于指定的最⼩值@Max(value) 被注释的元素必须是⼀个数字,其值必须⼩于等于指定的最⼤值@DecimalMin(value) 被注释的元素必须是⼀个数字,其值必须⼤于等于指定的最⼩值@DecimalMax(value) 被注释的元素必须是⼀个数字,其值必须⼩于等于指定的最⼤值@Size(max=, min=) 被注释的元素的⼤⼩必须在指定的范围内@Digits (integer, fraction) 被注释的元素必须是⼀个数字,其值必须在可接受的范围内@Past 被注释的元素必须是⼀个过去的⽇期@Future 被注释的元素必须是⼀个将来的⽇期@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式复制代码3.hiberate validation 注解复制代码@Email 被注释的元素必须是电⼦邮箱地址@Length(min=,max=) 被注释的字符串的⼤⼩必须在指定的范围内@NotEmpty 被注释的字符串的必须⾮空@Range(min=,max=,message=) 被注释的元素必须在合适的范围内@URL(protocol=,host=, port=,regexp=, flags=) 合法的url复制代码主要区分下@NotNull @NotEmpty @NotBlank 3个注解的区别:@NotNull 任何对象的value不能为null@NotEmpty 集合对象的元素不为0,即集合不为空,也可以⽤于字符串不为null@NotBlank 只能⽤于字符串不为null,并且字符串trim()以后length要⼤于04. 案例HualalaRegistVO.java复制代码import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.hibernate.validator.constraints.NotBlank;import javax.validation.constraints.NotNull;import javax.validation.constraints.Pattern;import java.math.BigDecimal;/***@Author: jiyang@Date: 2018-06-27 13:48*/@Data@AllArgsConstructor@NoArgsConstructorpublic class HualalaRegistVO {@NotBlank@Pattern(regexp = "^\d{11}$", message = "⼿机号码格式错误")String phoneNumber; //⼿机号码@NotBlankString name; //姓名@NotBlankString loanBody;//借款主体@NotBlankString loanBodyId;//借款主体ID@NotNullBigDecimal borrowAmount;//借款⾦额@NotNullBigDecimal turnover;//⽉营业额@NotNullBigDecimal profit; //⽉利润@NotBlankString usage;//⽤途@NotBlank(groups = {A.clss})String groupID;//集团IDString source = ""; //来源String code; //验证码(更换⼿机号码时使⽤)String ipAddress; //ip地址 // 定义两个域 public Interface {}public Interface{}}复制代码controller复制代码@RequestMapping(value = "/regist", method = {RequestMethod.GET, RequestMethod.POST})@ResponseBodypublic Object hualalaRegist(@Validated({HualalaRegistVO.A.class}) HualalaRegistVO registVO, BindingResult bindingResult, HttpServletRequest request) throws Exception {if(bindingResult.hasErrors())return new ResultBean<>(HttpStatus.SC_BAD_REQUEST,"请求参数错误",null);if (!"dev".equals(profile)) {registVO.setPhoneNumber(LongdaiUtil.decrypt(registVO.getPhoneNumber()));registVO.setGroupID(LongdaiUtil.decrypt(registVO.getGroupID()));}registVO.setIpAddress(NetworkUtil.getIpAddress(request));return hualalaService.hualalaRegist(registVO);}复制代码5. custom validation复制代码@Documented@Retention(RUNTIME)@Target({FIELD, ANNOTATION_TYPE, PARAMETER})@Constraint(validatedBy = AdultValidator.class)public @interface Adult {String message() default "{adult}";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };}复制代码复制代码@Componentpublic class AdultValidator implements ConstraintValidator<Adult, LocalDate> {private static final int ADULT_AGE = 18;@Overridepublic boolean isValid(LocalDate dateOfBirth, ConstraintValidatorContext constraintValidatorContext) { return dateOfBirth != null && LocalDate.now().minusYears(ADULT_AGE).isAfter(dateOfBirth);}}复制代码@NotNull@Past@Adultprivate LocalDate dateOfBirth;。
一、各种注解方式1.@Autowired注解(不推荐使用,建议使用@Resource)@Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。
@Autowired的标注位置不同,它们都会在Spring在初始化这个bean时,自动装配这个属性。
要使@Autowired能够工作,还需要在配置文件中加入以下Xml代码1.<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>2. @Qualifier注解@Autowired是根据类型进行自动装配的。
例如,如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。
我们可以使用@Qualifier配合@Autowired来解决这些问题。
如下:1). 可能存在多个UserDao实例Java代码1.@Autowired2.@Qualifier("userServiceImpl")3.public IUserService userService;或者Java代码1.@Autowired2.public void setUserDao(@Qualifier("userDao") UserDao userDao) {erDao = userDao;4.}这样,Spring会找到id为userServiceImpl和userDao的bean进行装配。
2). 可能不存在UserDao实例Java代码1.@Autowired(required = false)2.public IUserService userService;3. @Resource注解JSR-250标准注解,推荐使用它来代替Spring专有的@Autowired注解。
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按byName 自动注入罢了。
@Resource有两个属性是比较重要的,分别是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。
所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType 自动注入策略。
如果既不指定name也不指定type属性,这时将通过反射机制使用byName 自动注入策略。
要使@Autowired能够工作,还需要在配置文件中加入以下: Xml代码1.<bean class="monAnnotationBeanPostProcessor"/>@Resource装配顺序:a.如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常b.如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常c.如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常d.如果既没有指定name,又没有指定type,则自动按照byName方式进行装配(见2);如果没有匹配,则回退为一个原始类型(UserDao)进行匹配,如果匹配则自动装配;4. @PostConstruct(JSR-250)注解在方法上加上注解@PostConstruct,这个方法就会在Bean初始化之后被Spring容器执行(注:Bean初始化包括,实例化Bean,并装配Bean的属性(依赖注入))。
它的一个典型的应用场景是,当你需要往Bean里注入一个其父类中定义的属性,而你又无法复写父类的属性或属性的setter方法时,如:Java代码1.public class UserDaoImpl extends HibernateDaoSupport implements UserDao {2.3.private SessionFactory mySessionFacotry;4.5.@Resource6.public void setMySessionFacotry(SessionFactory sessionFacotry)7. {8.this.mySessionFacotry = sessionFacotry;9. }10.11.@PostConstruct12.public void injectSessionFactory()13. {14.super.setSessionFactory(mySessionFacotry);15. }16.}这里通过@PostConstruct,为UserDaoImpl的父类里定义的一个sessionFactory私有属性,注入了我们自己定义的 sessionFactory(父类的setSessionFactory方法为final,不可复写),之后我们就可以通过调用 super.getSessionFactory()来访问该属性了。
5. @PreDestroy(JSR-250)注解在方法上加上注解@PreDestroy,这个方法就会在Bean初始化之后被Spring容器执行。
其用法同@PostConstruct。
和@PostConstruct 区别在于:@PostConstruct注释的方法将在类实例化后调用,而标注了 @PreDestroy 的方法将在类销毁之前调用。
6. @Component注解 (不推荐使用)只需要在对应的类上加上一个@Component注解,就将该类定义为一个Bean了。
Spring 还提供了更加细化的注解形式:@Repository、@Service、@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean。
目前版本(2.5)中,这些注解与@Component的语义是一样的,完全通用,在Spring以后的版本中可能会给它们追加更多的语义。
所以,我们推荐使用@Repository、@Service、@Controller来替代@Component。
7.@Scope注解在使用XML定义Bean时,我们可能还需要通过bean的scope属性来定义一个Bean的作用范围,我们同样可以通过@Scope注解来完成这项工作:Java代码1.@Scope("session")2.@Component()3.public class UserSessionBean implements Serializable{4. ... ...5.}二、配置启用注解(注意以下配置需要使用spring2.5的头文件,在spring3.0中不适用)1.使用简化配置Spring2.1添加了一个新的context的Schema命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。
我们知道注释本身是不会做任何事情的,它仅提供元数据信息。
要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。
AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor就是处理这些注释元数据的处理器。
但是直接在Spring配置文件中定义这些Bean显得比较笨拙。
Spring为我们提供了一种方便的注册这些BeanPostProcessor的方式,这就是,以下是spring的配置。
Xml代码1.<beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="http://www/schema/context"2.xsi:schemaLocation="/schema/beans3. /schema/beans/spring-beans-2.5.xsd4. /schema/context5. /schema/context/spring-context-2.5.xsd">6.<context:annotation-config/>7.beans>将隐式地向Spring容器注册了AutowiredAnnotationBeanPostProcessor 、CommonAnnotationBeanPostProcessor 、PersistenceAnnotationBeanPostProcessorRequiredAnnotationBeanPostProcessor这4个BeanPostProcessor。
2.使用让Bean定义注解工作起来Xml代码1.<beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="http://www/schema/context"2.xsi:schemaLocation="/schema/beans3. /schema/beans/spring-beans-2.5.xsd4. /schema/context5. /schema/context/spring-context-2.5.xsd">6.<context:component-scan base-package="com.kedacom.ksoa"/>7.beans>这里,所有通过元素定义Bean的配置内容已经被移除,仅需要添加一行配置就解决所有问题了——Spring XML配置文件得到了极致的简化(当然配置元数据还是需要的,只不过以注释形式存在罢了)。
的base-package属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
还允许定义过滤器将基包下的某些类纳入或排除。
Spring支持以下4种类型的过滤方式:过滤器类型 | 表达式范例 | 说明注解 | org.example.SomeAnnotation | 将所有使用SomeAnnotation注解的类过滤出来类名指定 | org.example.SomeClass | 过滤指定的类正则表达式 | com\.kedacom\.spring\.annotation\.web\..* | 通过正则表达式过滤一些类AspectJ表达式 | org.example..*Service+ | 通过AspectJ表达式过滤一些类以正则表达式为例,我列举一个应用实例:Xml代码1.<context:component-scan base-package="com.casheen.spring.annotation">2.<context:exclude-filter type="regex"expression="com\.casheen\.spring\.annotation\.web\..*"/>3.context:component-scan>值得注意的是配置项不但启用了对类包进行扫描以实施注释驱动Bean定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),因此当使用后,就可以将移除了。