作为一名ruby转java的程序员,首先就是懵在各种java&spring注解上…
java注解
运行机制分类
- 源码注解:注解只在源码中存在,编译成.class文件就不存在了
- 编译时注解:注解在源码和.class文件中都存在。(例如:JDK的三个注解)
- 运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解
来源分类
- 来自JDK的注解:三个@Override @Deprecated @SuppressWarning
- 来自第三方的注解:比如Spring框架、Mybatis框架的注解等等
- 我们自己定义的注解
JDK自带注解
- @Override 表示当前方法覆盖了父类的方法
- @Deprecation 表示方法已经过时,方法上有横线,使用时会有警告。
- @SuppviseWarnings 表示关闭一些警告信息(通知java编译器忽略特定的编译警告)
自定义注解 - 元注解
java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
@Retention – 定义该注解的生命周期, 什么时候使用该注解
- RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
- RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
- RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
@Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
- ElementType.CONSTRUCTOR:用于描述构造器
- ElementType.FIELD:成员变量、对象、属性(包括enum实例)
- ElementType.LOCAL_VARIABLE:用于描述局部变量
- ElementType.PACKAGE:用于描述包
- ElementType.PARAMETER:用于描述参数
- ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Documented – 一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中
@Inherited – 定义该注释和子类的关系, 是否允许子类继承该注解
@Inherited元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
自定义注解类编写规则
- Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口.
- 参数成员只能用public或默认(default)这两个访问权修饰
- 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
- 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法
- 注解也可以没有定义成员, 不过这样注解就没啥用了
PS:自定义注解需要使用到元注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
String value() default "";
}
spring常用注解
声明bean注解
@Component - 注解在类上,可以作用在任何层次, 泛化的概念
@Service - 注解在类上,用于标注业务层组件
@Controller - 注解在类上,用于标注控制层组件
@Repository - 注解在类上,用于标注数据访问组件,即DAO组件
@Component、@Repository、@Service、@Controller实质上属于同一类注解,用法相同,功能相同,区别在于标识组件的类型
@Service(value="SecUserService")
public class SecUsersServiceImpl implements SecUsersService {
@Autowired
private SecUsersDao secUsersDao;
@Autowired
private SecRoleUserService secRoleUserService;
public void doBusiness(){
//do some business
}
}
@Bean - 注解在方法上, 声明当前方法的返回值为一个Bean
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),
"/druid/*");
servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
servletRegistrationBean.addInitParameter("deny", "192.168.0.1");
servletRegistrationBean.addInitParameter("loginUsername", "admin");
servletRegistrationBean.addInitParameter("loginPassword", "123456");
servletRegistrationBean.addInitParameter("resetEnable", "false");
return servletRegistrationBean;
}
@Primary - 自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常, 与@Component or @Bean 一起使用
@Scope - 注解在类或方法上,描述的是Spring容器如何新建Bean的实例的,通常与@Component or @Bean 一起使用
- Singleton,一个spring容器中只要一个Bean的实例,此为Spring的默认配置,全容器共享一个实例
- Prototype,每次调用新建一个Bean实例
- Request,Web项目中,给每一个http request新建一个Bean实例
- Session,Web项目中,给每一个http session新建一个Bean实例
- GlobalSession,这个只在portal应用中有用,给每一个global http session 新建一个Bean实例
@Controller("demo")
@Scope("Prototype")
public class demo {
}
注入Bean注解
@Autowired - 可以对成员变量、方法、构造函数、类,进行注释, 默认按类型装配
注解在set方法上或属性上 如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。
@Autowired @Qualifier("staff")
private People people;
@Autowired
public PeopleService(@Qualifier("staff") People people) {
...
}
@Resource - 来自于java EE规范的一个annotation, 有一个name属性, 在默认情况下,spring将这个值解释为需要被注入的Bean实例的名字
配置注解
@Configuration - 注解在类上,声明当前类是一个配置类,相当于一个Spring配置的xml文件
把一个类作为一个IoC容器 和@Bean搭配使用,某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean
@ComponentScan - 注解在类上,自动扫描包名下所有使用@Service、@Compent、@Repository、@Controller的类注册为Bean
@Lazy(true) - 表示延迟初始化
资源调用
@Value - 注解在变量上, 调用资源(普通文件,网址,配置文件,系统环境变量等)
- 默认值
@Value("true") private boolean defaultBoolean;
- Spring Environment Property
@Value("${APP_NAME_NOT_FOUND}") private String defaultAppName;
- 系统环境变量
@Value("${java.home}") private String javaHome;
- java home system property
@Value("#{systemProperties['java.home']}") private String javaHome;
- 注释在方法上
@Value("Test")
public void printValues(String s, String v){} //both 's' and 'v' values will be 'Test'
@Value("Test")
public void printValues(String s, @Value("Data") String v){}
// s=Test, v=Data
@PropertySource - 注解在类上, 目的是加载指定的属性文件
@PropertySource("classpath:conf/config.properties")
public class SystemConfig {
...
}
@PropertySources({@PropertySource("classpath:conf/config.properties"), @PropertySource("classpath:conf/config1.properties")})
public class SystemConfig {
...
}
@Profile - 作用在类、方法上,在不同情况下选择激活不懂的config。
@Profile("Development") //指定profile为Development
@Configuration
public class DevDatabaseConfig implements DatabaseConfig {
@Override
@Bean
public DataSource createDataSource() {
System.out.println("Creating DEV database");
DriverManagerDataSource dataSource = new DriverManagerDataSource();
/*
* Set MySQL specific properties for Development Environment
*/
return dataSource;
}
}
@ActiveProfiles("Development") //激活Development profile
public class TestActiveProfile {
@Autowired
private HelloService hs;
@Test
public void testProfile() throws Exception {
String value = hs.sayHello();
System.out.println(value);
}
}
@ImportResource("classpath:ws-client.xml")
- 加载xml配置
Bean的初始化和销毁
@PostConstruct - 注解在方法上,在构造函数执行后执行
@PreDestroy- 注解在方法上,在Bean销毁之前执行
@Component
public class Chinese
{
...
@PostConstruct
public void init()
{
System.out.println("正在执行初始化的init方法...");
}
@PreDestroy
public void close()
{
System.out.println("正在执行销毁之前的close方法...");
}
}
@DependsOn - 注解在方法上,定义Bean初始化及销毁时的顺序
@Configuration
public class AppConfig {
@Bean("beanOne")
@DependsOn(value = { "beanTwo", "beanThree" }) //beanTwo, beanThree初始化后才初始化beanOne
public BeanOne getBeanOne() {
return new BeanOne();
}
@Bean("beanTwo")
public BeanTwo getBeanTwo() {
return new BeanTwo();
}
@Bean("beanThree")
public BeanThree getBeanThree() {
return new BeanThree();
}
}
spring AOP注解
@Aspect - 注解在类上, 声明是一个切面
@After - 注解在方法上, 在目标方法返回或抛出异常后调用
@PointCut - 注解在方法上, 定义拦截规则,声明切点
@AfterReturning - 注解在方法上, 通常方法会在目标方法返回后调用
@AfterThrowing - 注解在方法上,通知方法会在目标方法抛出异常后调用
@Around - 注解在方法上, 通知方法将目标方法封装起来
@Before - 注解在方法上, 通知方法会在目标方法执行之前执行
@EnableAspectJAutoProxy - JavaConfig类上使用注解@EnableAspectJAutoProxy注解启动自动代理功能,@Aspect才能生效
@Aspect
public class Audience {
/**
* 定义一个公共的切点
*/
@Pointcut("execution(** com.spring.aop.service.Perfomance.perform(..))")
public void performance() {
}
/**
* 目标方法执行之前调用
*/
@Before("performance()")
public void silenceCellPhone() {
System.out.println("Silencing cell phones");
}
/**
* 目标方法执行之前调用
*/
@Before("performance()")
public void takeSeats() {
System.out.println("Taking seats");
}
/**
* 目标方法执行完后调用
*/
@AfterReturning("performance()")
public void applause() {
System.out.println("CLAP CLAP CLAP");
}
/**
* 目标方法发生异常时调用
*/
@AfterThrowing("performance()")
public void demandRefund() {
System.out.println("Demanding a refund");
}
/**
* 环绕通知
* @param jp 通过它调用目标方法
*/
@Around("perforance()")
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("Silencing cell phones");
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP!!!");
} catch (Throwable e) {
System.out.println("Demanding a refund");
}
}
}
spring事务注解
@Transactional - 可以作用于接口、接口方法、类以及类方法上
当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。
- propagation
PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作 - readOnly - 事务的读写属性,取true或者false,true为只读、默认为false
- rollbackFor - 回滚策略,当遇到指定异常时回滚。譬如上例遇到异常就回滚
- timeout - (补充的) 设置超时时间,单位为秒
- isolation - 设置事务隔离级别,枚举类型,一共五种
DEFAULT 采用数据库默认隔离级别
READ_UNCOMMITTED 读未提交的数据(会出现脏读取) READ_COMMITTED 读已提交的数据(会出现幻读,即前后两次读的不一样)
REPEATABLE_READ 可重复读,会出现幻读
SERIALIZABLE 串行化(对资源消耗较大,一般不使用)
@Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDAO companyDAO;
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
public int deleteByName(String name) {
int result = companyDAO.deleteByName(name);
return company;
}
...
}
spring mvc注解
@RequestMapping - 类,方法上,用来映射Web请求(访问路径和参数)、处理类和方法的
- @RequestMapping 既可以作用在类级别,也可以作用在方法级别。当它定义在类级别时,标明该控制器处理所有的请求都被映射到 /favsoft 路径下
- @RequestMapping中可以使用 method 属性标记其所接受的方法类型,如果不指定方法类型的话,可以使用 HTTP GET/POST 方法请求数据,但是一旦指定方法类型,就只能使用该类型获取数据
- @GetMapping, @PostMapping, @DeleteMapping, @PutMapping
@ResponseBody - 类,返回值前,方法上, 将返回类型直接输入到HTTP response body中, 输出JSON格式的数据
@RequestBody - 参数前, request的参数在请求体内
@RequestMapping(value = "/something", method = RequestMethod.PUT) public void handle(@RequestBody String body, Writer writer) throws IOException { writer.write(body); }
@PathVariable - 参数前,接收路径参数
@RestController - 类上,组合注解 = @Controller+@ResponseBody
@RequestParam - 参数中,将请求的参数绑定到方法中的参数上,如下面的代码所示。
其实,即使不配置该参数,注解也会默认使用该参数。如果想自定义指定参数的话,如果将@RequestParam的 required 属性设置为false(@RequestParam(value=”id”,required=false))
spring-boot 注解
@SpringBootApplication - SpringBoot的核心注解,主要作用是开启自动配置
@SpringBootApplication=@ComponentScan+@Configuration+@EnableAutoConfiguration
关闭特定的自动配置:@SpringBootApplication注解的exclude参数。
例如:@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class} )