注解是什么
Annotation(注解)是JDK1.5及以后版本引入的,注解是以‘@注解名’在代码中存在的,是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能,当然注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
常用注解
@Service:注解在类上,表示这是一个业务层bean
package com.example.demo.service;
import org.springframework.stereotype.Service;
//如果有多个类继承UserService 接口则需要用第一个注解指定不同的名字
//@Service("userService")
@Service
public class UserServiceImpl implements UserService{
...
}
@Controller:注解在类上,表示这是一个控制层bean
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
...
}
@Repository:注解在类上,表示这是一个数据访问层bean
@Component:注解在类上,表示这是一个组件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 {
//自动把UserService 接口的实现类实例化给userService变量
@Autowired
//如果有多个类实现了UserService接口,则我们需要按名注入
//则要结合@Qualifier("userService1") 注解装载指定的实现类
//@Qualifier("userService1")
//@Autowired + @Qualifier = @Resource
//@Resource(name = "userService1")
private UserService userService;
}
说明: @Autowired属于Spring的;@Resource为JSR-250标准的注释,属于J2EE的。
@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
@Configuration:注解在类上,表示这是一个IOC容器,相当于spring的配置文件,java配置的方式。 IOC容器的配置类
@Bean: 注解在方法上,声明当前方法返回一个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());
}
使用
//这个dataSource就是我们在ExampleConfiguration中配的DataSource
@Autowired
private DataSource dataSource;
说明:
@Configuration可理解为用spring的时候xml里面的<beans>标签
@Bean可理解为用spring的时候xml里面的<bean>标签
@PostConstruct:注解在方法上,构造函数执行后执行。
@PreDestroy: 注解在方法上,在Bean销毁前执行。
@ComponentScan:注解在类上,扫描标注了@Controller等注解的类,注册为bean
@Lazy(true):延迟初始化
可以解决循环依赖,首先说一下什么是依赖循环,比如:我现在有一个ServiceA需要调用ServiceB的方法,那么ServiceA就依赖于ServiceB,那在ServiceB中再调用ServiceA的方法,就形成了循环依赖。Spring在初始化bean的时候就不知道先初始化哪个bean就会报错。代码如下:
public class ClassA {
@Autowired
@Lazy //如果不加就会报错
ClassB classB;
}
public class ClassB {
@Autowired
@Lazy //如果不加就会报错
ClassA classA ;
}
当然循环依赖在项目中尽量避免
@Scope:注解在类上,描述spring容器如何创建Bean实例。
Scope描述的是Spring容器如何新建Bean实例的。Spring的Scope有以下几种,通过@Scope注解来实现。
- singleton:一个Spring容器中只有一个Bean的实例,此为Spring的默认配置,全容器共享一个实例。
- prototype:每次调用新建一个Bean实例。
- request:Web项目中,给每一个 http request 新建一个Bean实例。
- session:Web项目中,给每一个 http session 新建一个Bean实例。
- globalSession:这个只在portal应用中有用,给每一个 global http session 新建一个Bean实例。
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
测试代码
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
//读取application.properties 文件spring.datasource.url 这个内容
@Value("${spring.datasource.url}")
private String dataSourceURL;
}
@Profile:注解在方法 类上 在不同情况下选择实例化不同的Bean 特定环境下生效
public interface DBConnector {
public void configure();
}
//测试数据库
@Component
@Profile("testdb")
public class TestDBConnector implements DBConnector {
@Override
public void configure() {
System.out.println("testdb");
}
}
// 生产数据库
@Component
@Profile("devdb")
public class DevDBConnector implements DBConnector {
@Override
public void configure() {
System.out.println("devdb");
}
}
application.properties
spring.profiles.active=testdb
测试
@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:约定优于配置
@WebServlet(name="Servlet3FirstDemo",value="/Servlet3FirstDemo")
@WebFilter将一个实现了javax.servlet.Filte接口的类定义为过滤器
第三方servlet:使用ServletRegistrationBean来注入servlet,对于每一个servlet都有一个ServletRegistrationBean来注入。
@RestController = @RestController + @ResponseBody + @Controller
@RequestBody
@RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
JAVA
@RequestMapping(value = "user/login")
@ResponseBody
// 将ajax(datas)发出的请求写入 User 对象中,返回json对象响应回去
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("出现异常,异常信息:"+textStatus,"error");
}
});
};
@PathVariable:映射 URL 绑定的占位符
- 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
- 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
//@PathVariable可以用来映射URL中的占位符到目标方法的参数中
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable:"+id);
return SUCCESS;
}
@RequestMapping
@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。
下面是一个同时在类和方法上应用了 @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 的请求会由 get() 方法来处理,而到 /home/index 的请求会由 index() 来处理。
详细的RequestMapping请参见这边文章:https://www.oschina.net/translate/using-the-spring-requestmapping-annotation