javaday16

1   回顾

l  基础API

n  API - Application Programming Interface

       应用编程接口,一切可以调用的东西

n  Object

u  toString() 默认格式"类型@地址"

u  equals(Object) 比较是否相等,默认==比地址

u  hashCode() 获得一个对象的哈希值

u  wait()

u  notify()

u  notifyAll()

扫描二维码关注公众号,回复: 11268007 查看本文章

n  String

u  封装 char[] 数组

u  常量池

u  不可变

u  加号连接效率低

String s1 = "aaa"

String s2 = "bbb"

String s3 = "ccc"

String s4 = s1+s2+s3

 

加号连接过程:

sb = new StringBuilder("aa");

sb.append("bb");

s = sb.toString();

 

String s4 = "aaa"+"bbb"+"ccc"

编译优化: String s4 = "aaabbbccc"

 

n  StringBuilder/StringBuffer

u  用来代替字符串,做高效率字符串连接运算

u  append()

u  内部char[]数组默认初始容量 16

u  翻倍增长 +2

n  正则表达式

u  百度"正则表达式大全", "用户名正则", "密码正则", "日期正则"

u  字符串的正则匹配运算方法:

s.matches(正则)

u  拆分: s.split(";")

u  替换: s.replaceAll(正则, 子串)

 

n  Integer

u  int的包装类

u  创建实例:

l  new Integer(6)

l  Integer.valueOf(6)

Integer类内部,存在一个Integer[]数组,其中缓存了256个Integer实例,封装的数字范围:-128到127

范围内的值,访问缓存对象

范围外的值,新建实例

n  Date/SimpleDateFormat

 

l  集合

n  ArrayList

u  数组

u  访问任意位置效率高

u  增删数据,效率可能降低

u  默认初始容量10

n  LinkedList

u  双向链表

u  两端效率高

n  HashMap

u  哈希表,散列表

u  键:

l  不重复

l  无序

u  哈希运算过程:

l  key.hashCode()用哈希值计算下标i

l  键值对封装成Entry对象,放入i位置

 

 

 

 

 

2         第十六天:高级:手写JUnit+手写@Value+手写DI

l  今天没有新的知识点

l  难度非常高的练习

l  今天的练习不影响后面学习

 

 

2.1 配置信息注入到对象中

新建项目: day16

 

右键点击项目--build path--add external ...

 

 

 

 

 

application.yml

 

yaml - yet another markup language - 夜猫

 

不能使用tab制表符,都要使用空格

同一层次,必须对齐,至少两个空格2

冒号后面需要加空格

 

在src下新建文件 application.yml

spring:

  datasource:

    driver: com.mysql.jdbc.Driver

    username: root

    password: "123456"

    url: jdbc:mysql://127.0.0.1:3306/jt?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai

 

 

加载yml文件的工具类

 

 

使用 jackson 提供了 yaml 数据处理工具,来读取解析yml配置文件

 

加载后的数据结构:三层map

 

 

package day16;

 

import java.io.File;

import java.net.URLDecoder;

import java.util.HashMap;

import java.util.Map;

 

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

 

import ognl.Ognl;

import ognl.OgnlException;

 

public class Configure {

    private static Map<String, String> cfg = new HashMap<String, String>();

   

    public static void load() throws Exception {

       String path = Configure.class.getResource("/application.yml").getPath();

       path = URLDecoder.decode(path, "UTF-8");

      

       ObjectMapper mapper = new ObjectMapper(new YAMLFactory());

       cfg = mapper.readValue(new File(path), Map.class);

    }

   

    public static String get(String expr) {

       expr = expr.trim();

       expr = expr.substring(2, expr.length()-1);

       String r;

       try {

           r = (String) Ognl.getValue(expr, cfg);

           return r;

       } catch (OgnlException e) {

           e.printStackTrace();

           return null;

       }

    }

   

    public static void main(String[] args) throws Exception {

       Configure.load();

       System.out.println(cfg);

       String driver = get("${spring.datasource.driver}");

       String username = get("${spring.datasource.username}");

       String password = get("${spring.datasource.password}");

       String url = get("${spring.datasource.url}");

       System.out.println(driver);

       System.out.println(username);

       System.out.println(password);

       System.out.println(url);

    }

}

 

 

Component注解

 

package day16;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface Component {

}

 

 

Value注解

 

package day16;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Value {

    String name() default "";

    String value() default "";

}

 

 

UserDao

l  有Component注解才创建对象,没有注解不创建对象

l  Value注解把配置文件中的配置数据赋给变量

 

package day16;

 

@Component

public class UserDao {

    @Value("${spring.datasource.driver}")

    private String driver;

    @Value("${spring.datasource.username}")

    private String username;

    @Value("${spring.datasource.password}")

    private String password;

    @Value("${spring.datasource.url}")

    private String url;

   

    public void test() {

       System.out.println("\n---UserDao中注入的JDBC连接信息--------------------");

       System.out.println(driver);

       System.out.println(username);

       System.out.println(password);

       System.out.println(url);

    }

}

 

 

用下面的测试代码测试我们要实现的功能

 

package day16;

 

import java.lang.reflect.Field;

 

public class TestValue {

    public static void main(String[] args) throws Exception {

       Configure.load();

      

       String className = "day16.UserDao";

       Class<?> c = Class.forName(className);

       if(c.isAnnotationPresent(Component.class)) {

           Object obj = c.newInstance();

          

           Field[] a = c.getDeclaredFields();

           for (Field f : a) {

              if (f.isAnnotationPresent(Value.class)) {

                  Value v = f.getAnnotation(Value.class);

                  String name = v.name();

                  if (name==null || name.equals("")) {

                     name = v.value();

                  }

                  String r = Configure.get(name);

                  f.setAccessible(true);

                  f.set(obj, r);

              }

           }

 

           ///////////////////////

           UserDao dao = (UserDao) obj;

           dao.test();

       }

    }

}

 

 

 

2.2 自动扫描并创建对象

 

l  IoC - Inverse of Control

控制翻转,自己不控制对象的创建,而是权利翻转,交给工具来创建对象

需要对象,从工具来取用

 

l  DI - Dependency Injection

依赖注入

对象需要的数据,使用的其他对象,进行自动装配

 

 

自动在类路径中扫描,找到所有添加了以下注解的类,并自动创建实例

l  Component

l  Service

l  Controller

 

 

SpringContext - Spring环境对象,上下文对象

包含一个map集合:

key

value

"day16.UserDao"

UserDao实例

"day16.UserService"

UserService实例

"day16.UserController"

UserController实例

 

 

/

 |- day16

      |- UserDao

      |- UserService

      |- UserControler

      |- pojo

           |- A

           |- B

           |- xxx

                |- ...

 |- day15

      |- X

      |- Y

   

   

 

 

 

 

 

 

 

 

 

在对象种,对添加了@Autowired注解的变量进行自动注入

 

Service注解

 

package day16;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface Service {

}

 

Controller注解

 

package day16;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

public @interface Controller {

}

 

Autowired注解

 

package day16;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Autowired {

}

 

UserService

 

package day16;

 

@Service

public class UserService {

    @Autowired

    private UserDao userDao;

   

    public void test() {

       System.out.println("\n----UserService中注入的dao对象------------------------");

       System.out.println(userDao);

       userDao.test();

    }

}

 

UserController

 

package day16;

@Controller

public class UserController {

    @Autowired

    private UserService userService;

   

    public void test() {

       System.out.println("\n----UserController中注入的service对象------------------------");

       System.out.println(userService);

       userService.test();

    }

}

 

SpringContext

先完成第一步,扫描类路径下的类,并自动创建实例

 

package day16;

 

import java.io.File;

import java.util.HashMap;

import java.util.Map;

 

public class SpringContext {

    private static Map<String, Object> ctx = new HashMap<String, Object>();

   

    public static void autoScan() throws Exception {

       String path = SpringContext.class.getResource("/").getPath();

       File dir = new File(path);

       scan(dir, new StringBuilder());

    }

 

    private static void scan(File dir, StringBuilder pkg) throws Exception {

       File[] files = dir.listFiles();

       if(files == null) return;

      

       for (File f : files) {

           String name = f.getName();

          

           if (f.isFile()) {

              if (name.endsWith(".class")) {

                  handle(pkg.toString()+"."+f.getName().substring(0, name.length()-6));

              }

           } else {

              if (pkg.length()!=0) {

                  pkg.append(".");

              }

              pkg.append(name);

              scan(f, pkg);

              pkg.delete(pkg.length()-name.length(), pkg.length());

           }

       }

    }

 

    private static void handle(String className) throws Exception {

       System.out.println(className);

       Class<?> c = Class.forName(className);

       if (c.isAnnotationPresent(Component.class) ||

              c.isAnnotationPresent(Service.class) ||

              c.isAnnotationPresent(Controller.class)) {

           Object obj = c.newInstance();

           ctx.put(className, obj);

       }

    }

   

    public static void main(String[] args) throws Exception {

       autoScan();

       System.out.println(ctx);

    }

}

 

 

 

SpringContext

完成第二步,对象中的变量自动注入,完成对象的自动装配

 

package day16;

 

import java.io.File;

import java.lang.reflect.Field;

import java.util.HashMap;

import java.util.Map;

 

public class SpringContext {

    private static Map<String, Object> ctx = new HashMap<String, Object>();

   

    static {

       try {

           Configure.load();

       } catch (Exception e) {

           e.printStackTrace();

       }

    }

   

    public static void autoScan() throws Exception {

       String path = SpringContext.class.getResource("/").getPath();

       File dir = new File(path);

       scan(dir, new StringBuilder());

      

       autowire();

    }

 

    private static void autowire() throws Exception {

       for (Object obj : ctx.values()) {

           Class<? extends Object> c = obj.getClass();

           Field[] fields = c.getDeclaredFields();

           for (Field f : fields) {

              if (f.isAnnotationPresent(Value.class)) {

                  injectValue(obj, f);

              }

              if (f.isAnnotationPresent(Autowired.class)) {

                  injectObject(obj, f);

              }

           }

       }

    }

 

    private static void injectValue(Object obj, Field f) throws Exception {

       Value v = f.getAnnotation(Value.class);

       String name = v.name();

       if (name==null || name.equals("")) {

           name = v.value();

       }

       String r = Configure.get(name);

       f.setAccessible(true);

       f.set(obj, r);

    }

 

    private static void injectObject(Object obj, Field f) throws Exception {

       f.setAccessible(true);

       String name = f.getType().getName();

       Object obj2 = ctx.get(name);

       f.set(obj, obj2);

    }

 

    private static void scan(File dir, StringBuilder pkg) throws Exception {

       File[] files = dir.listFiles();

       if(files == null) return;

      

       for (File f : files) {

           String name = f.getName();

          

           if (f.isFile()) {

              if (name.endsWith(".class")) {

                  handle(pkg.toString()+"."+f.getName().substring(0, name.length()-6));

              }

           } else {

              if (pkg.length()!=0) {

                  pkg.append(".");

              }

              pkg.append(name);

              scan(f, pkg);

              pkg.delete(pkg.length()-name.length(), pkg.length());

           }

       }

    }

 

    private static void handle(String className) throws Exception {

       System.out.println(className);

       Class<?> c = Class.forName(className);

       if (c.isAnnotationPresent(Component.class) ||

              c.isAnnotationPresent(Service.class) ||

              c.isAnnotationPresent(Controller.class)) {

           Object obj = c.newInstance();

           ctx.put(className, obj);

       }

    }

   

    public static <V> V getObject(Class<V> c) {

       return (V) ctx.get(c.getName());

    }

   

    public static void main(String[] args) throws Exception {

       autoScan();

       System.out.println(ctx);

       UserController c = getObject(UserController.class);

       c.test();

    }

}

 

 

 

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/ou-yang/p/12957668.html
今日推荐