spring
@Autowired
-
标注在属性上。
-
默认是将属性名作为组件的id注入到容器中。
-
自动导入对象到类中,注意导入的对象也要被spring容器管理 比如说:service类注入到controller类中
@Qualifier
搭配@Autowired注解使用,可以指定组件的名称,而不是使用属性名。
自己指定组件的名称
@Autowired
@Qualifier(value="bookDao2")
private BookDao bookDao;
@Scope
-
设置作用域
-
标注在bean方法对象上,不用设置,因为默认是单实例。我们常用的也是单实例。
@Scope("prototype")//单实例属于默认作用域,IOC容器启动的时候就会调用方法创建对象,以后每次获取都是从Spring容器当中拿同一个对象(map当中)。
@Scope("prototype")//多实例,在IOC容器启动创建的时候,并不会直接创建对象放在容器中去,当你需要调用的时候,才会从容器当中获取该对象然后进行创建。
@Bean(附比较@Component)
二者不同详见http://t.csdn.cn/SXBel
-
@Bean需要在配置类中使用,即类上需要加上@Configuration注解,然后在配置类中使用一个方法定义bean是如何创建的
-
设置该方法的返回值作为spring管理的bean
-
用于声明某个方法返回一个由 Spring 管理的 bean 实例。这个方法的返回值就是一个 bean 对象,通常,这些方法在配置类中用于定义一些需要特定配置的 bean,例如第三方库的对象、外部服务的连接等。
package com.itheima.config;
import com.itheima.testnouser.user;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public user myBean() {
return new user("站三",3);
}
}
package com.itheima.testnouser;
public class user{
private String name;
private Integer id;
public user() {
}
public user(String name, Integer id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}
package com.itheima.testnouser;
import com.itheima.config.AppConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class demo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
user myBean = context.getBean(user.class);
System.out.println(myBean.getName());//输出站三
context.close();
}
}
二者异同
1、@Component注解表明一个类会作为组件类,并告知Spring要为这个类创建bean。
2、@Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的bean。通常方法体中包含了最终产生bean实例的逻辑。
两者的目的是一样的,都是注册bean到Spring容器中。
区别:
@Component(@Controller、@Service、@Repository)通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中。
而@Bean注解通常是我们在标有该注解的方法中定义产生这个bean的逻辑。
@Component 作用于类,@Bean作用于方法。
总结:
@Component和@Bean都是用来注册Bean并装配到Spring容器中,但是Bean比Component的自定义性更强。可以实现一些Component实现不了的自定义加载类。
@Profile
@Profile
注解是 Spring 框架中用于定义在特定条件下激活或禁用 bean 注册的一种方式。通过使用 @Profile
注解,你可以根据特定的环境、配置或其他条件来控制哪些 bean 应该被创建和注册到 Spring 容器中。
@Profile
注解的作用是:
-
条件化注册: 使用
@Profile
注解,你可以将 bean 注册与特定的运行时环境或配置相关联。只有在满足指定的条件时,标有相应@Profile
注解的 bean 才会被注册到 Spring 容器中。 -
环境分离: 如果你的应用程序需要在不同的环境中运行,比如开发、测试和生产环境,你可以使用不同的
@Profile
注解来定义相应环境下所需的 bean。这样可以避免将不必要的组件加载到不同环境中。
下面是一个示例,演示了如何使用 @Profile
注解:
@Configuration
public class AppConfig {
@Bean
@Profile("development")
public DataSource developmentDataSource() {
return new DevelopmentDataSource();
}
@Bean
@Profile("production")
public DataSource productionDataSource() {
return new ProductionDataSource();
}
}
@Profile
注解是 Spring 框架中用于定义在特定条件下激活或禁用 bean 注册的一种方式。通过使用 @Profile
注解,你可以根据特定的环境、配置或其他条件来控制哪些 bean 应该被创建和注册到 Spring 容器中。
@Profile
注解的作用是:
-
条件化注册: 使用
@Profile
注解,你可以将 bean 注册与特定的运行时环境或配置相关联。只有在满足指定的条件时,标有相应@Profile
注解的 bean 才会被注册到 Spring 容器中。 -
环境分离: 如果你的应用程序需要在不同的环境中运行,比如开发、测试和生产环境,你可以使用不同的
@Profile
注解来定义相应环境下所需的 bean。这样可以避免将不必要的组件加载到不同环境中。
@Configuration
public class AppConfig {
@Bean
@Profile("development")
public DataSource developmentDataSource() {
return new DevelopmentDataSource();
}
@Bean
@Profile("production")
public DataSource productionDataSource() {
return new ProductionDataSource();
}
}
在这个示例中,developmentDataSource()
方法标记了 @Profile("development")
注解,表示该方法返回的 bean 仅在设置了 "development" 环境时被注册。类似地,productionDataSource()
方法标记了 @Profile("production")
注解,表示该方法返回的 bean 仅在设置了 "production" 环境时被注册。
你可以通过在启动应用程序时指定不同的环境参数(如通过启动参数 -Dspring.profiles.active=development
或者在 Spring Boot 中使用 application.properties
文件)来激活特定的 @Profile
。这样,只有与当前环境匹配的 bean 会被注册到 Spring 容器中。
总之,@Profile
注解使你能够根据不同条件对 bean 进行条件化注册,从而实现在不同环境下加载不同的组件。
@RestController
- 标注在类上,标识该类是一个控制器bean
- @Controller和@ResponseBody的合集。REST风格 ;前后端不分离。
- 将函数的返回值直接填入到HTTP响应体中,返回JSON或XML数据,显示在浏览器。因为如果只是使用@Controller(传统springmvc应用)的话,我们一般都是返回一个视图。
@Component和衍生注解
- 要想把类标识成可以被@Autowired注解自动装配的bean的类,就需要加入这些注解。并且将该类交给IOC容器存储,Component一般加在工具类上面
- 特殊的@Service(service层、@Controller(controller层)、@Mapper(DAO层)
@ComponentScan
@ComponentScan注解是一个Spring的注解,用于扫描包上的注解将组件加载到IOC容器中。
它的出现主要是对标component-scan标签,标签只能使用在xml的配置文件中,而现在越来越流行使用注解的形式注册bean
@ComponentScan注解只能使用在有@Configuration配置注解的地方,因为component-scan标签必须存在于xml配置文件中;而在脱离xml使用时,需要使用带有在@Configuration配置注解上。并不局限与一定是 @Configuration也可以是@SpringBootConfiguration…
作用:扫描被@Controller、@Service、@Repository、@Component等注解标注的类。
原文链接:https://blog.youkuaiyun.com/weixin_43808717/article/details/118179660
@Configuration
- 用来代替 applicationContext.xml 配置文件,所有这个配置文件里面能做到的事情都可以通过这个注解所在类来进行注册。
-
声明配置类: 通过在一个类上添加
@Configuration
注解,你可以告诉Spring容器,这个类是一个包含了Bean定义的配置类。 -
Bean定义: 在
@Configuration
注解的类中,你可以使用@Bean
注解来定义Spring Bean。@Bean
注解告诉Spring容器,一个方法的返回值应该被注册为一个Bean,并且可以在整个应用程序中被使用。 -
代替XML配置: 在过去,Spring应用程序通常使用XML配置来定义Bean。但是使用
@Configuration
注解,你可以采用Java代码来代替繁琐的XML配置,使配置更加清晰和类型安全。 - proxyBeanMethods: 是用来控制在
@Configuration
类中的@Bean
方法是否通过代理机制来管理,以确保Bean的正确性和一致性。意味着每次调用这些@Bean
方法时,Spring会检查容器中是否已经存在相应的Bean实例,如果存在,就直接返回实例,否则就创建一个新的实例并添加到容器中。@Configuration(proxyBeanMethods = true) (保证每个@Bean方法被调用多少次返回的组件都是单实例的)(默认)
@Configuration(proxyBeanMethods = false)(每个@Bean方法被调用多少次返回的组件都是新创建的)
@Configuration
注解允许你在Java类中以代码方式定义和配置Spring Bean,取代了传统的XML配置方式。
@Value
Value是将与配置文件中的键对应的值分配给其带注解的属性。@Value 注解可以用来将外部的值动态注入到 Bean 中,在 @Value 注解中,可以使${} 与 #{} ,它们的区别如下:
(1)@Value("${}"):可以获取对应属性文件中定义的属性值。
(2)@Value("#{}"):表示 SpEl 表达式通常用来获取 bean 的属性,或者调用 bean 的某个方法。
1.基本数值
// 直接将字符串赋值给 str 属性
@Value("hello world")
private String str;
@Test
public void getValue(){
System.out.println(str);//输出hello world
}
2.可以写SpEL:#{}
@Value("#{20-2}")
private Integer age;//输出18,
3.可以写${},取出配置文件(properties、yml ...)中的值
yml配置文件中user
password:root
@Value("${user.password}")
private String password;
@Test
public void getPassword(){
System.out.println(password);//输出root
}
4、注入其他bean
//其他bean,自定义名称为 myBeans
@Component("myBeans")
public class OtherBean {
@Value("OtherBean的NAME属性")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//测试程序
@RunWith(SpringRunner.class)
@SpringBootTest()
@ContextConfiguration(classes = PdaAndIpadApplication.class)
public class ValueController {
@Value("#{myBeans.name}")
private String fromAnotherBean;
@Test
public void getValue(){
System.out.println(fromAnotherBean);//输出OtherBean的NAME属性
}
}
@Transactional
默认情况下,只有出现RuntimeException才回滚事务,也就是运行时异常,编译时异常不回滚,而下面的rollbackFor可以指定回滚类型
@Transactional(rollbackFor = Exception.class) //spring事务管理
例如解散该部门后,也要解散该部门下的所有员工,为了保证结果的一致性,应该开启事务
@Transactional
@Override
public void delete(Integer id) throws Exception {
try {
deptMapper.deleteById(id); //根据ID删除部门数据
// int i = 1/0;
//if(true){throw new Exception("出错啦...");}
empMapper.deleteByDeptId(id); //根据部门ID删除该部门下的员工
} finally {
DeptLog deptLog = new DeptLog();
deptLog.setCreateTime(LocalDateTime.now());
deptLog.setDescription("执行了解散部门的操作,此次解散的是"+id+"号部门");
deptLogService.insert(deptLog);
}
}
@Transactional开启事务后,两个操作中有一个执行失败,都会回滚事务
springMVC
@ResponseBody
用于指示一个方法返回的值应该被序列化为HTTP响应的正文。它通常在控制器方法中使用,用于将方法返回的数据(如对象、字符串等)转换成HTTP响应的内容。
具体来说,当一个方法被标记了 @ResponseBody
注解时,Spring会自动将方法的返回值转换为适当的格式,比如JSON、XML等,然后将它作为HTTP响应的正文发送给客户端。
@Controller
public class MyController {
@ResponseBody
@RequestMapping("/hello")
public String hello() {
return "Hello, World!";
}
@ResponseBody
@RequestMapping("/data")
public SomeDataObject getData() {
SomeDataObject data = new SomeDataObject();
return data;
}
}
在上面的示例中,@ResponseBody
注解被用于两个不同的方法。对于 /hello
路径,返回的字符串 "Hello, World!" 会直接作为HTTP响应的内容返回给客户端。对于 /data
路径,方法返回的 SomeDataObject
对象会被转换为JSON或XML格式,并作为HTTP响应的正文返回给客户端。
@GetMapping
- 标注在方法上
@GetMapping("users") 等价于 @RequestMapping(value="/users",method=RequestMethod.GET)
@POSTMapping
- 标注在方法上
@PostMapping("users") 等价于 @RequestMapping(value="/users",method=RequestMethod.POST)
@PutMapping
- 标注在方法上
@PutMapping("/users/{userId}") 等价于 @RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)
@DeleteMapping
- 标注在方法上
@DeleteMapping("/users/{userId}")等价于 @RequestMapping(value="/users/{userId}",method=RequestMethod.DE
@RequestMapping
路径抽取
@Controller
@RequestMapping("/example") // 类级别的映射
public class ExampleController {
@RequestParam
- 这个注解用于从URL查询字符串中提取参数。当客户端通过URL的查询字符串(即
?key=value
形式)传递参数时,你可以使用@RequestParam
将这些参数的值映射到方法的参数中。 - 请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam 绑定参数关系
- 用于从查询字符串中提取参数,适用于一般的GET请求。
@RestController
public class RequestController {
//数组集合参数
@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
System.out.println(hobby);
return "OK";
}
}
@PathVariable
-
用于获取路径参数,使用{参数名称}描述路径参数
@PathVariable
: 这个注解用于从URL路径中提取参数。当URL中包含占位符时,你可以使用 @PathVariable
将这些占位符的值映射到方法的参数中。
示例:
@GetMapping("/user/{userId}")
public String getUser(@PathVariable Long userId) {
// 使用 userId 进行处理
}
@RequestBody
- 这个注解用于从请求体中读取数据,通常用于处理POST请求或其他需要发送数据到服务器的请求。读取请求的body部分且Content-Type 为 application/json格式的数据,接收到数据之后会自动将数据绑定到 java对象上。
- 用于读取请求体中的数据,适用于POST请求或其他需要发送数据的请求。
例如
@PostMapping("/data")
public ResponseEntity<String> postData(@RequestBody DataObject data) {
// 使用 data 进行处理
}
@RequestHeader
- 获取请求头
@CookieValue
- 获取Cookie值
Spring-AOP
基础概念
- @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行 - @Before:前置通知,此注解标注的通知方法在目标方法前被执行 - @After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行 - @AfterReturning : 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行 - @AfterThrowing : 异常后通知,此注解标注的通知方法发生异常后执行连接点:JoinPoint,可以被AOP控制的方法,暗含方法执行的相关信息 通知:Advice,指哪些重复li的逻辑,也就是共性功能(最终体现在一个方法) 切入点表达式,匹配连接点的条件,通知仅会在切入点方法执行时被应用 @Pointcut("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))") 切面:Aspect,描述通知与切入点的对应关系(通知+切入点) 目标对象:Target,通知所应用的对象 方法的签名:由方法的名称和形参列表组成,具体来说,一个方法的签名由它的名称以及它的形参的个数、修饰符和类型组成。
@Aspect
声明切点,即定义拦截规则,确定有哪些方法会被切入 |
@PointCut
声明一个切面(就是说这是一个额外功能) |
在Spring中用JoinPoint抽象了连接点,用它可以获得方法执行时的相关信息,如目标类名、方法名、方法参数等。
- 对于@Around通知,获取连接点信息只能使用ProceedingJoinPoint类型
- 对于其他四种通知,获取连接点信息只能使用JoinPoint,它是ProceedingJoinPoint的父类型
@Slf4j
@Component
@Aspect
public class MyAspect1 {
//我们要针对哪些特定的方法进行编程,声明切入点表达式,抽取共同部分,可以在其他切面类使用
@Pointcut("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")
public void pt(){}
@Before("pt()")
public void before(){
log.info("before ...");
}
@Around("pt()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
log.info("around before ...");
//调用目标对象的原始方法执行
Object result = proceedingJoinPoint.proceed();
log.info("around after ...");
return result;
}