注解&反射API讲解视频
注解(Annontation)是JAVA5引入的一种代码辅助工具,他的核心作用是对类、方法、变量、参数和包进行标注,通过反射来访问这些标注信息,以此在运行时改变锁注解对象的行为。JAVA中的注解由内置注解和元注解组成。
普通注释编译后class文件中不存在。
而注解附加的信息则根据需要可以保存到class文件中,甚至运行期加载的class对象中
代码:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.TYPE})
public @interface study{
String name() default "foxgl";//java 基本类型
String[] mores;
}
// 调用时
@Study(mores = {"hard","easy"})
注解的创建方式:
1.配置元注解,由元注解来当前注解的作用范围和生命周期。
2.注解中如果需要添加信息,可以用以上方式添加。
3.注解信息支持java的基本数据结构。
反射:
反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射。
优缺点:
1.通过反射可以使程序代码访问装载到JVM中的类的内部信息,获取已装载类的属性信息,获取已装载类的方法,获取已装载类的构造方法信息。
2.反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。
3.反射会对性能造成一定的影响,同时让代码的可读性变低。
API:
import com.foxgl.tools.annotation.Study;
import lombok.Data;
@Study(name="class",mores = {"hard","easy"}) //ElementType.TYPE
@Data
public class Person {
@Study(name="field",mores = {"hard","easy"}) //ElementType.FIELD
private String name;
private int age;
@Override
@Study(name="method",mores = {"hard","easy"}) //ElementType.METHOD
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.foxgl.tools.annotation.Study;
import com.foxgl.tools.domain.Person;
public class ReflectionDemo {
public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InstantiationException, NoSuchMethodException, SecurityException, InvocationTargetException {
Person person = new Person();
Class<? extends Person> aClass = person.getClass();//类元信息
//Spring bean name="person" class="com.foxgl.tools.domain.Person"
Class<?> bClass = Class.forName("com.foxgl.tools.domain.Person");//Spring
//实例1 通过反射获取类名,包名
System.out.println("实例1 通过反射获取类名,包名");
String name = aClass.getName();
String simpleName = aClass.getSimpleName();
System.out.println("className["+name+"]");
// com.foxgl.tools.domain.Person
System.out.println("classSimpleName["+simpleName+"]");
// Person
System.out.println("aClass["+aClass+"]");
// class com.foxgl.tools.domain.Person
System.out.println("bClass["+bClass+"]");
// class com.foxgl.tools.domain.Person
//实例2 类属性
System.out.println("实例2 遍历类属性");
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println("类属性["+field+"]");
}
//实例3 获取属性具体值
System.out.println("实例3 获取属性具体值");
person.setName("rio");
person.setAge(10);
for (Field field : declaredFields) {
field.setAccessible(true);
System.out.println("类属性["+field+"]"+"类的值["+field.get(person)+"]");
}
//实例4 反射
System.out.println("实例4 反射中实例化");
Object p = aClass.newInstance();//相当于在反射中实例化
for (Field field : declaredFields) {
field.setAccessible(true);
if(field.getName().equals("name")){
field.set(p, "foxgl");
System.out.println("设置name属性=foxgl");
}else if(field.getName().equals("age")){
field.set(p, 20);
System.out.println("设置age属性=20");
}
}
System.out.println(p);
//实例5 反射获取当前类的方法
System.out.println("实例5 反射获取当前类的方法");
Method[] methods = aClass.getMethods();
for(Method method : methods){
System.out.println("方法["+method.getName()+"]");
}
Method m1 = aClass.getMethod("setName", declaredFields[0].getType());
//实例6 obj方法返回值
System.out.println("实例6 反射执行method");
p = new Person();
Object obj1 = m1.invoke(p, "helloWorld");
System.out.println(p);
System.out.println("返回值:"+obj1);
Method m2 = aClass.getMethod("toString");
Object obj2 = m2.invoke(p);
System.out.println("返回值:"+obj2);
//实例7 获取注解
System.out.println("实例7 获取注解");
Study classAnnotation = aClass.getAnnotation(Study.class);//获取 类注解
String[] mores = classAnnotation.mores();
for (int i = 0; i < mores.length; i++) {
System.out.println(mores[i]);
}
String name1 = classAnnotation.name();
System.out.println("mores["+mores+"] name1["+name1+"]");
for(Method method : methods){
Study methodAnnotation = method.getAnnotation(Study.class);//获取 方法注解
if(methodAnnotation == null)
continue;
String name2 = methodAnnotation.name();
mores = methodAnnotation.mores();
System.out.println("mores["+mores+"] name2["+name2+"]");
}
for(Field field : declaredFields){
Study fieldAnnotation = field.getAnnotation(Study.class);//获取 属性注解
if(fieldAnnotation == null)
continue;
String name3 = fieldAnnotation.name();
mores = fieldAnnotation.mores();
System.out.println("mores["+mores+"] name3["+name3+"]");
}
}
}
通过注解,实现动态生成SQL
import com.foxgl.tools.annotation.Column;
import com.foxgl.tools.annotation.SqlState;
import lombok.Data;
@Data
@SqlState("t_order")//表名
public class Order {//sql select 字段 from 表名 where 条件
@Column//字段
private Long id;
@Column("order_no")
private String orderNo;//一旦有值,就是条件
@Column("shop_id")
private int shopId;
@Column("user_name")
private String userName;
@Column("user_id")
private int userId;
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SqlState {
String value();//表名
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Column {
String value() default "";//字段名
}
import java.lang.reflect.Field;
import com.foxgl.tools.annotation.Column;
import com.foxgl.tools.annotation.SqlState;
import com.foxgl.tools.domain.Order;
public class GenerateSqlUtil {
public String query(Object tab) throws Exception{
StringBuffer sb = new StringBuffer();
//select 字段 from 表名 where 条件
sb.append("select");
StringBuffer sb2 = new StringBuffer();
//反射机制
//表名
Class<?> clz = tab.getClass();
SqlState sqlState = clz.getAnnotation(SqlState.class);
if(sqlState == null){
throw new RuntimeException("注解缺失");
}
String tableName = sqlState.value();
//字段
Field[] fields = clz.getDeclaredFields();
int i = 1;
for(Field field : fields){
Column column = field.getAnnotation(Column.class);
if(column == null)
continue;//没写就不生成查询字段
if(column.value().equals("")){//表字段名和属性名一致
field.setAccessible(true);
String fieldName = field.getName();
Object o = field.get(tab);
if(o != null && Integer.parseInt(o.toString()) != 0){
if(i>1){
sb2.append(" and "+fieldName+"="+o);
sb.append(" "+fieldName+",");
}else{
sb2.append(" where "+fieldName+"="+o);
sb.append(" "+fieldName+",");
}
i++;
}
}else{
sb.append(" "+ column.value() + " ,");
field.setAccessible(true);
Object o = field.get(tab);
if(o != null && Integer.parseInt(o.toString()) != 0){
if(i > 1){
sb2.append(" and "+column.value()+"="+o);
}else{
sb2.append(" where "+column.value()+"="+o);
}
i++;
}
}
}
sb.deleteCharAt(sb.length() - 1);//删除最后的逗号
sb.append(" from " + tableName);
sb.append(sb2);
return sb.toString();
}
public static void main(String[] args) throws Exception {
GenerateSqlUtil util = new GenerateSqlUtil();
Order order = new Order();
order.setOrderNo("7778888");
order.setShopId(1234);
String s = util.query(order);
System.out.println(s);
}
}
注解之框架封装实战
代理模式
静态代理:
//基类游戏工厂
public interface GameFactory {
@Override
public String make();
}
//PS4游戏工厂
public class PS4Factory implements GameFactory{
@Override
public String make() {
return "PS4";
}
}
//游戏机工厂
public class GameBoyFactory implements GameFactory{
@Override
public String make() {
return "GameBoy";
}
}
import com.foxgl.tools.pattern.proxy.service.BaseFactory;
import com.foxgl.tools.pattern.proxy.service.GameFactory;
public class RioProxy implements GameFactory{
BaseFactory baseFactory;
public RioProxy(BaseFactory baseFactory) {
this.baseFactory = baseFactory;
}
@Override
public String make() {
doSomeThingBefore();
System.out.println(baseFactory.make());
doSomeThingAfter();
return null;
}
private void doSomeThingAfter() {
System.out.println("执行RioProxy.doSomeThingAfter()");
}
private void doSomeThingBefore() {
System.out.println("执行RioProxy.doSomeThingBefore()");
}
}
//静态代理 调用main
PS4Factory factory = new PS4Factory();
RioProxy proxy = new RioProxy(factory);
proxy.make();
动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class RioProxy2 implements InvocationHandler {
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public Object getProxy() {// 只负责跟总公司联系,不在去接触具体店铺
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Long startTime = doSomeThingBefore();
Object obj = method.invoke(target, args);
System.out.println(obj);
Long endTime = doSomeThingAfter();
System.out.println(endTime - startTime);
return null;
}
private Long doSomeThingAfter() {
return System.currentTimeMillis();
}
private Long doSomeThingBefore() {
return System.currentTimeMillis();
}
}
//动态代理
RioProxy2 proxy22 = new RioProxy2();
proxy22.setTarget(new PS4Factory());
GameFactory gameFactory = (GameFactory)proxy22.getProxy();
gameFactory.make();