注解是什么
Annotation(注解)是JDK1.5及以后版本引入的,注解是以‘@注解名’在代碼中存在的渡八,是附加在代碼中的一些元信息,用于一些工具在編譯坞古、運(yùn)行時(shí)進(jìn)行解析和使用梆惯,起到說(shuō)明酱鸭、配置的功能,當(dāng)然注解不會(huì)也不能影響代碼的實(shí)際邏輯垛吗,僅僅起到輔助性的作用凹髓。
常用注解
@Service:注解在類上,表示這是一個(gè)業(yè)務(wù)層bean
package com.example.demo.service;
import org.springframework.stereotype.Service;
//如果有多個(gè)類繼承UserService 接口則需要用第一個(gè)注解指定不同的名字
//@Service("userService")
@Service
public class UserServiceImpl implements UserService{
...
}
@Controller:注解在類上怯屉,表示這是一個(gè)控制層bean
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
...
}
@Repository:注解在類上蔚舀,表示這是一個(gè)數(shù)據(jù)訪問層bean
@Component:注解在類上,表示這是一個(gè)組件bean
@Autowired:按類型裝配
@Resource: 按名稱裝配
package com.example.demo.controller;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
//自動(dòng)把UserService 接口的實(shí)現(xiàn)類實(shí)例化給userService變量
@Autowired
//如果有多個(gè)類實(shí)現(xiàn)了UserService接口锨络,則我們需要按名注入
//則要結(jié)合@Qualifier("userService1") 注解裝載指定的實(shí)現(xiàn)類
//@Qualifier("userService1")
//@Autowired + @Qualifier = @Resource
//@Resource(name = "userService1")
private UserService userService;
}
說(shuō)明: @Autowired屬于Spring的赌躺;@Resource為JSR-250標(biāo)準(zhǔn)的注釋,屬于J2EE的足删。
@Autowired默認(rèn)按類型裝配寿谴,默認(rèn)情況下必須要求依賴對(duì)象必須存在,如果要允許null 值失受,可以設(shè)置它的required屬性為false讶泰,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用
@Configuration:注解在類上拂到,表示這是一個(gè)IOC容器痪署,相當(dāng)于spring的配置文件,java配置的方式兄旬。 IOC容器的配置類
@Bean: 注解在方法上狼犯,聲明當(dāng)前方法返回一個(gè)Bean
@Configuration
public class ExampleConfiguration {
@Value("com.mysql.jdbc.Driver")
private String driverClassName;
@Value("jdbc://xxxx.xx.xxx/xx")
private String driverUrl;
@Value("${root}")
private String driverUsername;
@Value("123456")
private String driverPassword;
@Bean(name = "dataSource")
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(driverUrl);
dataSource.setUsername(driverUsername);
dataSource.setPassword(driverPassword);
return dataSource;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
使用
//這個(gè)dataSource就是我們?cè)贓xampleConfiguration中配的DataSource
@Autowired
private DataSource dataSource;
說(shuō)明:
@Configuration可理解為用spring的時(shí)候xml里面的<beans>標(biāo)簽
@Bean可理解為用spring的時(shí)候xml里面的<bean>標(biāo)簽
@PostConstruct:注解在方法上,構(gòu)造函數(shù)執(zhí)行后執(zhí)行领铐。
@PreDestroy: 注解在方法上悯森,在Bean銷毀前執(zhí)行。
@ComponentScan:注解在類上绪撵,掃描標(biāo)注了@Controller等注解的類瓢姻,注冊(cè)為bean
@Lazy(true):延遲初始化
可以解決循環(huán)依賴,首先說(shuō)一下什么是依賴循環(huán)音诈,比如:我現(xiàn)在有一個(gè)ServiceA需要調(diào)用ServiceB的方法幻碱,那么ServiceA就依賴于ServiceB,那在ServiceB中再調(diào)用ServiceA的方法细溅,就形成了循環(huán)依賴褥傍。Spring在初始化bean的時(shí)候就不知道先初始化哪個(gè)bean就會(huì)報(bào)錯(cuò)。代碼如下:
public class ClassA {
@Autowired
@Lazy //如果不加就會(huì)報(bào)錯(cuò)
ClassB classB;
}
public class ClassB {
@Autowired
@Lazy //如果不加就會(huì)報(bào)錯(cuò)
ClassA classA ;
}
當(dāng)然循環(huán)依賴在項(xiàng)目中盡量避免
@Scope:注解在類上喇聊,描述spring容器如何創(chuàng)建Bean實(shí)例恍风。
Scope描述的是Spring容器如何新建Bean實(shí)例的。Spring的Scope有以下幾種,通過(guò)@Scope注解來(lái)實(shí)現(xiàn)朋贬。
- singleton:一個(gè)Spring容器中只有一個(gè)Bean的實(shí)例鸥咖,此為Spring的默認(rèn)配置,全容器共享一個(gè)實(shí)例兄世。
- prototype:每次調(diào)用新建一個(gè)Bean實(shí)例。
- request:Web項(xiàng)目中啊研,給每一個(gè) http request 新建一個(gè)Bean實(shí)例御滩。
- session:Web項(xiàng)目中,給每一個(gè) http session 新建一個(gè)Bean實(shí)例党远。
- globalSession:這個(gè)只在portal應(yīng)用中有用削解,給每一個(gè) global http session 新建一個(gè)Bean實(shí)例。
package com.example.demo.config;
import org.springframework.context.annotation.Scope;
@Scope("singleton")
public class DataSourceConfig {
...
}
@Value:注解在變量上沟娱,從配置文件中讀取氛驮。
application.properties 文件
server.port=8080
debug=true
# DataSource
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
測(cè)試代碼
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
//讀取application.properties 文件spring.datasource.url 這個(gè)內(nèi)容
@Value("${spring.datasource.url}")
private String dataSourceURL;
}
@Profile:注解在方法 類上 在不同情況下選擇實(shí)例化不同的Bean 特定環(huán)境下生效
public interface DBConnector {
public void configure();
}
//測(cè)試數(shù)據(jù)庫(kù)
@Component
@Profile("testdb")
public class TestDBConnector implements DBConnector {
@Override
public void configure() {
System.out.println("testdb");
}
}
// 生產(chǎn)數(shù)據(jù)庫(kù)
@Component
@Profile("devdb")
public class DevDBConnector implements DBConnector {
@Override
public void configure() {
System.out.println("devdb");
}
}
application.properties
spring.profiles.active=testdb
測(cè)試
@RestController
@RequestMapping("/task")
public class TaskController {
@Autowired
DBConnector connector ;
@RequestMapping(value = {"/",""})
public String hellTask(){
connector.configure(); //最終打印testdb
return "hello task !! myage is " + myage;
}
}
@SpringBootApplication:@SpringBootApplication=@ComponentScan+@Configuration+@EnableAutoConfiguration:約定優(yōu)于配置
@WebServlet(name="Servlet3FirstDemo",value="/Servlet3FirstDemo")
@WebFilter將一個(gè)實(shí)現(xiàn)了javax.servlet.Filte接口的類定義為過(guò)濾器
第三方servlet:使用ServletRegistrationBean來(lái)注入servlet济似,對(duì)于每一個(gè)servlet都有一個(gè)ServletRegistrationBean來(lái)注入矫废。
@RestController = @RestController + @ResponseBody + @Controller
@RequestBody
@RequestBody 注解則是將 HTTP 請(qǐng)求正文插入方法中,使用適合的 HttpMessageConverter 將請(qǐng)求體寫入某個(gè)對(duì)象砰蠢。
JAVA
@RequestMapping(value = "user/login")
@ResponseBody
// 將ajax(datas)發(fā)出的請(qǐng)求寫入 User 對(duì)象中,返回json對(duì)象響應(yīng)回去
public User login(User user) {
User user = new User();
user.setUserid(1);
user.setUsername("MrF");
user.setStatus("1");
return user ;
}
function login() {
var datas = '{"username":"' + $('#username').val() + '",
"userid":"' + $('#userid').val() + '",
"status":"' + $('#status').val() + '"}';
$.ajax({
type : 'POST',
contentType : 'application/json',
url : "${pageContext.request.contextPath}/user/login",
processData : false,
dataType : 'json',
data : datas,
success : function(data) {
alert("userid: " + data.userid +
"username: " + data.username +
"status: "+ data.status);
},
error : function(XMLHttpRequest, textStatus, errorThrown) {
alert("出現(xiàn)異常蓖扑,異常信息:"+textStatus,"error");
}
});
};
@PathVariable:映射 URL 綁定的占位符
- 帶占位符的 URL 是 Spring3.0 新增的功能,該功能在SpringMVC 向 REST 目標(biāo)挺進(jìn)發(fā)展過(guò)程中具有里程碑的意義
- 通過(guò) @PathVariable 可以將 URL 中占位符參數(shù)綁定到控制器處理方法的入?yún)⒅校篣RL 中的 {xxx} 占位符可以通過(guò)@PathVariable(“xxx“) 綁定到操作方法的入?yún)⒅小?/li>
//@PathVariable可以用來(lái)映射URL中的占位符到目標(biāo)方法的參數(shù)中
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable:"+id);
return SUCCESS;
}
@RequestMapping
@RequestMapping 是 Spring Web 應(yīng)用程序中最常被用到的注解之一台舱。這個(gè)注解會(huì)將 HTTP 請(qǐng)求映射到 MVC 和 REST 控制器的處理方法上律杠。
下面是一個(gè)同時(shí)在類和方法上應(yīng)用了 @RequestMapping 注解的示例:
@RestController
@RequestMapping("/home")
public class IndexController {
@RequestMapping("/")
String get() {
//mapped to hostname:port/home/
return "Hello from get";
}
@RequestMapping("/index")
String index() {
//mapped to hostname:port/home/index/
return "Hello from index";
}
}
如上述代碼所示,到 /home 的請(qǐng)求會(huì)由 get() 方法來(lái)處理竞惋,而到 /home/index 的請(qǐng)求會(huì)由 index() 來(lái)處理柜去。
詳細(xì)的RequestMapping請(qǐng)參見這邊文章:https://www.oschina.net/translate/using-the-spring-requestmapping-annotation