Java注解Annotation
注解的作用:
1.生成文档。这是最常见的,也是Java最早提供的注解。常用的有@see,@param,@return等
2.跟踪代码依赖性,实现替代配置文件功能。比较常见的是Spring2.5开始的基于注解配置,作用就是减少配置。
3.在编译时进行格式检查。
注解的语法:
J2SE5内置了3种标准注解:
@Override,表示当前的方法定义将覆盖超类中的方法。
@Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是不赞成使用的代码,被弃用的代码。
@SuppressWarnings,关闭不当编译器警告信息。
元注解:负责注解其他注解,就是注解的注解。
@Target | 表示该注解可以用在什么地方 |
@Retention | 表示需要在什么级别保存盖住接信息,可选的RetentionPolicy参数有:source,class,runtime |
@Document | 将注解包含在javadoc中 |
@Inherited | 允许子类继承父类的注解 |
自定义一个注解:
注意事项:
- 注解的可用类型有以下几种:所有基本类型,String,Class,enum,Annotation,数组。不包括集合
- 元素不能有不确定的值,即要么有默认值,要么在使用注解时提供元素得值,而且不能用null作为默认值。
- 注解在只有一个元素且该元素的名称是value的情况下,在使用注解的时候可以省略"value=",直接写需要的值即可。
例如:
@Retention(RetentionPolicy.RUNTIME) public @interface Inject { String driverClass() default "com.mysql.jdbc.Driver"; String jdbcUrl() default "jdbc:mysql://localhost:3306/bookstore"; String user() default "root"; String password() default "root"; }
注解的应用(处理):这是最重要的部分,涉及到注解处理器。从原理上讲,注解处理器就是通过反射机制获取被检查方法上的注解信息。
例如下面的一个例子,在set方法上加上c3p0连接池的注解信息,通过daoFactory解析注解信息创建一个连接。
1.Inject.java文件
package cn.itcast.annotation2; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface Inject { String driverClass() default "com.mysql.jdbc.Driver"; String jdbcUrl() default "jdbc:mysql://localhost:3306/bookstore"; String user() default "root"; String password() default "root"; }
2.BookDao.java文件
package cn.itcast.annotation2; import com.mchange.v2.c3p0.ComboPooledDataSource; import cn.itcast.domain.Book; public class BookDao { @Inject private ComboPooledDataSource ds; //class @Inject public void setDs(ComboPooledDataSource ds) { this.ds = ds; } public ComboPooledDataSource getDs() { return ds; } public void add(Book book){ } }
3.DaoFactory.java文件
package cn.itcast.annotation2; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class DaoFactory { public static BookDao createBookDao(){ BookDao dao = new BookDao(); //向dao注入一个池 //解析出dao所有属性 try{ BeanInfo info = Introspector.getBeanInfo(dao.getClass(),Object.class); PropertyDescriptor pds[] = info.getPropertyDescriptors(); for(int i=0;pds!=null && i<pds.length;i++){ //得到bean的每一个属性描述器 PropertyDescriptor pd = pds[i]; Method setMethod = pd.getWriteMethod(); //得到属性相应的set方法 //看set方法上有没有inject 注解 Inject inject = setMethod.getAnnotation(Inject.class); if(inject==null){ continue; } //方法有注解,则用注解配置的信息,创建一个连接池 Class propertyType = pd.getPropertyType(); Object datasource = propertyType.newInstance(); DataSource ds = (DataSource)createDataSourceByInject(inject,datasource); setMethod.invoke(dao, ds); } }catch (Exception e) { throw new RuntimeException(); } return dao; } //用注解的信息,为池配置属性 private static Object createDataSourceByInject(Inject inject,Object ds) { //获取到注解所有属性相应的方法 driverClass url equals hashcode Method methods[] = inject.getClass().getMethods(); for(Method m : methods){ String methodName = m.getName(); //equals url() password() PropertyDescriptor pd = null; try { pd = new PropertyDescriptor(methodName,ds.getClass()); //geturl Object value = m.invoke(inject, null); //得到注解属性的值 pd.getWriteMethod().invoke(ds, value); } catch (Exception e) { continue; } } return ds; } }
4、TestFactory.java文件
package cn.itcast.annotation2; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; public class TestFactory { public static void main(String[] args) throws SQLException { BookDao dao = DaoFactory.createBookDao(); DataSource ds = dao.getDs(); Connection conn= ds.getConnection(); System.out.println(conn); } }
运行后的结果:com.mchange.v2.c3p0.impl.NewProxyConnection@1d402894