├── day2.md ├── day3.md ├── day4.md ├── day5.md └── readme.md /day2.md: -------------------------------------------------------------------------------- 1 | # Day 2 2 | 3 | - [New Collector Class](#new-collector-class) 4 | - [Revamped Date/Time API](#revamped-datetime-api) 5 | - [Reflections Design Pattern using Proxy Class](#reflections-design-pattern-using-proxy-class) 6 | - [Write Javascript With Java](#write-javascript-with-java) 7 | - [CDI: Java Standard for Dependency Injection & Interception](#cdi-java-standard-for-dependency-injection-interception) 8 | - [Other New Features](#other-new-features) 9 | 10 | ## New Collector Class 11 | This further expands on the Stream API functionality. 12 | Contains a `groupingBy` method similar to a GROUP BY clause in a SQL query. 13 | ```java 14 | public Map getDVDsInEachGenre() { 15 | Map collect = DVDDao.getAllDVDs().collect(Collectors.groupingBy(DVD::getGenre, Collectors.counting())); 16 | return collect; 17 | } 18 | ``` 19 | Contains neat summarizing methods (though, don't expect it to print it out pretty). 20 | ```java 21 | public DoubleSummaryStatistics getPricingStats() { 22 | return DVDDao.getAllDVDs().collect(Collectors.summarizingDouble(DVD::getPrice)); 23 | } 24 | ``` 25 | 26 | ##Revamped Date/Time API 27 | Thread safe classes, domain-driven design. Manipulations can be chained (Fluent API). 28 | LocalDate (date only), LocalTime (time only) - note these are immutable and when manipulations are made, new instances are created. Example: 29 | ``` 30 | LocalDate ld = LocalDate.of(2015, Month.FEBRUARY, 29); 31 | ld.plusDays(1); 32 | System.out.println(ld) // will print 2015-02-29 not 2015-03-01 33 | ``` 34 | 35 | TemporalAdjuster allows for more complex date manipulations. 36 | 37 | ```java 38 | public static Appointment createFirstDayOfNextMonthAppointment(String description) { 39 | return new Appointment(description, LocalDateTime.of(LocalDate.now(), LocalTime.NOON).with(TemporalAdjusters.firstDayOfNextMonth())); 40 | } 41 | ``` 42 | 43 | ## Reflections Design Pattern using Proxy Class 44 | Imagine you had a Business object interface and its impl. And you had a TransactionManager that you want decoupled from Business obj, but want it to manage the transactional methods that are called by bus obj. 45 | 46 | Build an invoker as so (note: this code is rough, not compiled): 47 | ```java 48 | public class MyInvoker impelements InvocationHandler } 49 | BusinessObj target; 50 | TransactionManager mgr; 51 | 52 | public MyInvoker(BusinessObject target, TransactionMgr mgr) { 53 | this.target = target; 54 | this.mgr = mgr; 55 | } 56 | 57 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ 58 | Object result = null; 59 | mgr.startTransaction(); 60 | try { 61 | result = method.invoke(target, args); 62 | mgr.commit(); 63 | } catch( Exception e) { 64 | mgr.rollback(); 65 | } 66 | return result; 67 | } 68 | } 69 | ``` 70 | 71 | And to make the proxy handle it: 72 | ```java 73 | public class BusinessObjectFactory { 74 | public static BusinessObject getBusinessObject() { 75 | BusinessObject t = new BusinessObjectImpl(); 76 | TransactionManager mgr = new TransactionMgr(); 77 | InvocationHandler inv = new MyInvoker(t, mgr); 78 | try { 79 | // proxy creates a class that impls BusinessObject interface 80 | proxy = (BusinessObject) Proxy.newProxyInstance(BusinessObject.class.getClassLoader(), new Class[] {BusinessObject.class}, inv); 81 | } catch( Exception e) { 82 | 83 | } 84 | return proxy 85 | } 86 | } 87 | ``` 88 | And to use it: 89 | ```java 90 | public static void main(String[] args) { 91 | BusinessObject o = BusinessObjectFactoru.getBusinessObject() 92 | o.doStuff(); 93 | System.out.println(o); 94 | System.out.println(o.getClass().getName()); // will be proxy 95 | } 96 | ``` 97 | 98 | [More on it here.](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html) 99 | 100 | ##Write Javascript With Java 101 | Java 8 comes with the Nashorn Javascript Engine which allows you to write and eval Javascript code inside your Java code. There's an icecube joke somewhere here... 102 | 103 | Can access Javascript variables/methods from Java. Javascript scripts can implement Java interfaces. 104 | 105 | _Some_ will ask why? 106 | 107 | Suppose we have an email validation javascript function in a file (it implements our Java Validator interface). Here is an example of how we can invoke that Javascript function from Java. 108 | ```java 109 | public static boolean validateEmail(String email) throws ScriptException, NoSuchMethodException { 110 | 111 | // Get an instance of the ScriptEngineManager 112 | ScriptEngineManager sem = new ScriptEngineManager(); 113 | // Get the Nashorn scriptengine 114 | ScriptEngine se = sem.getEngineByName("Nashorn"); 115 | 116 | InputStream resource = ValidationService.class 117 | .getResourceAsStream("/Validation.js"); 118 | 119 | // evaluate the Validation resource 120 | se.eval(new InputStreamReader(resource)); 121 | 122 | // Get the Validator for validation of emails 123 | Validator v = (Validator) se.get("emailValidator"); 124 | 125 | // validate the email and return the result 126 | return (boolean) v.validate(email); 127 | } 128 | ``` 129 | 130 | ##CDI: Java Standard for Dependency Injection & Interception 131 | Context and Dependency Injection (CDI) allows us to ensure loosely coupled modules for our app. Following the principles of inversion of control/hollywood principle. Now Java ships with CDI, a DI framework, allowing us to use `@Inject` annotation to inject a dependency. For example: 132 | ```java 133 | @Inject 134 | private BlurayRepository repository; 135 | ``` 136 | 137 | This assumes we have a BlurayRepository interface and atleast one impl (otherwise we will get an ExceptionInInitializerError). 138 | 139 | ##Other New Features 140 | `Arrays.parallelSort`` assigns sorting tasks to multiple threads. More performant for larger arrays. 141 | 142 | Improved diamond operator usage, can do: `print(new Shop<>)` 143 | 144 | [Index](readme.md) | [Go to Day 3 >>](/day3.md) 145 | -------------------------------------------------------------------------------- /day3.md: -------------------------------------------------------------------------------- 1 | # Day 3 2 | 3 | - [CDI Cont'd: Using Qualifiers](#cdi-contd-using-qualifiers) 4 | - [Dealing With Data](#dealing-with-data) 5 | - [Websockets](#websockets) 6 | 7 | ## CDI Cont'd: Using Qualifiers 8 | To create a qualifier, first create a new annotation. For example, if we have a dependency called ActionRepository. Then, our new annotation would be: 9 | ```java 10 | @Qualifier 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ELementType.PARAMETER}) 13 | public @interface Action {} 14 | ``` 15 | 16 | The process of matching a bean to an injection point is called _typesafe resolution._ If you don't use a qualifier annotation like above, then the dependency/bean will automatically use @Default annotation. 17 | 18 | ###Using CDI with Servlets 19 | The `@Model` annotation allows us to say an object is going to be mapped to the frontend (controller/servlet/JSP). Similarily inorder for a bean to hold state during a client request we must define its scope. We do this using annotations such as: `@RequestScoped` (used for a single HTTP request) and `@ApplicationScoped` (used when you want to share state of the bean across all requests, ie you can use this on a DAO). We use `@Produces` for fields in a `@Model` object that we want to be mapped to the request scope. [More on it here.](http://docs.oracle.com/javaee/6/tutorial/doc/gjbbk.html) 20 | 21 | ##Dealing With Data 22 | ###JDBC 23 | The Java Database Connectivity (JDBC) API allows us to interface with data sources (not limited to relational db). As far as db connectivity goes, a pool of connections is created at container startup that will provide commands (close, get, use) to db connection requests from your code. This allows for efficient resourse reuse (pooling). 24 | 25 | To setup a datasource, simply define it as a resource in your context.xml. This basically makes it accessible to us in our code via JNDI like so: 26 | ```java 27 | @Resource(name = 'jdbc/WebShopDB') 28 | private DataSource ds; 29 | 30 | // later in your code, you would do: 31 | ds.getConnection(); 32 | ``` 33 | 34 | ###Java Persistance API (JPA) 35 | If you've used Hibernate, this is a generacized version of it. 36 | 37 | ##Websockets 38 | This isn't new but was covered in the course. Websockets allow for full-duplex (as opposed to HTTP which is half-duplex) async messaging. To setup websockets, you need to setup both endpoints (server and client). In Java, use the `@ServerEndpoint('/chat')` annotation to setup the server endpoint. Then in that class, create `void onOpen(Session s)`, `onMessage`, `onClose` methods. Since Websockets is a standard, you can also have your clientside endpoint using Javascript via `var webSocket = new WebSocket("ws://localhost:8080/project/chat")`. 39 | 40 | You can also define custom configurations for your endpoints such as having a decoders/encoders (for when you are sending more than a simple primitive type). 41 | ```java 42 | @ServerEndpoint(value="/auction", decoders=AuctionMessageDecoder.class) 43 | ``` 44 | 45 | [Index](readme.md) | [Go to Day 4 >>](/day4.md) -------------------------------------------------------------------------------- /day4.md: -------------------------------------------------------------------------------- 1 | # Day 4 2 | 3 | - [Asynchronous Servlets](#asynchronous-servlets) 4 | - [Spring MVC and REST Support](#spring-mvc-and-rest-support) 5 | - [GoF Patterns](#gof-patterns) 6 | 7 | ## Asynchronous Servlets 8 | We use servlets (think actions in controllers if you've used Rails or other MVC) to handle requests from the client. It used to be that a thread was created per client connection, however since Java 4, threads are allocated per client request. However this can still be problematic for long running requests. To solve this we make the servlet asyncronous (so that the request is handled by another thread): 9 | ```java 10 | @WebServlet(urlPatterns="/SearchFlight", asyncSupported=true) 11 | public class SearchFlightServlet extends HttpServlet { 12 | @Inject 13 | private FlightSearchService fss; 14 | 15 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) { 16 | AsyncContext atx = req.startAsync(); 17 | searchFlights(atx); 18 | } 19 | 20 | private void searchFlights(AsyncContext atx) { 21 | atx.start( () -> { 22 | ServletRequest r = atx.getRequest(); 23 | List flights = fss.searchFlights(r.getParameter("From"), r.getParameter("Destination"), r.getParameter("Date")); 24 | r.setAttribute("flightsFound", flights); 25 | atx.dispatch("/SearchResults.jsp"); 26 | }); 27 | } 28 | } 29 | ``` 30 | ___One should only spawn new threads within the AsyncContext or using ManagedExecutorService/ManagedScheduledExecutorService classes___ You can also add a listener to be able to monitor the lifecycle of the thread. 31 | 32 | Nowadays we have multiple requests/responses sent from within the same page, we can use Server-Sent Events (SSE) to handle them. SSE uses HTTP and not Websockets and has been standardized as part of HTML5. 33 | 34 | ##Spring MVC and REST Support 35 | When a request comes in to a Spring Servlet, a handler mapping tries to find the associated controller for that request (using what you configured in your .xml). There are also pre and post process objects that get invoked before/after controller executes. There could also be an AfterResponse object that occurs after our response goes to browser. The handler mapper manages this chain of events. 36 | 37 | The view resolver figures out which view corresponds to the page that we load up. In a RESTful approach, we suppress the view resolver logic so that we can send our content right from the controller to the browser. 38 | 39 | ```java 40 | @RequestMapping(value="/user.htm/{id}", method=RequestMethod.POST) 41 | public @ResponseBody String addUser(@ModelAttribute(value="user") User user, BindingResult r, @PathVariable("id") int id) 42 | ``` 43 | The `@ResponseBody` is what suppresses view resolver logic and a message converter takes over. The `@ModelAttribute` is able to take all the request params and bundle it into a User object that we have defined- any validation errors that may occur from bunding will be in the `BindingResult` var. 44 | 45 | Also if we were to return anything other than a primitive type, so like a `List` then it would automatiicaly be returned as a JSON. 46 | 47 | ## GoF Patterns 48 | 49 | ### Simplified Factory Pattern 50 | Instead of having seperate factories for each product objects and a main abstract factory class. You can just have a main factory class: 51 | ```java 52 | public class Factory { 53 | public Product getP(String name) throws Exception { 54 | String fullName = Class.forName("com.mike.products."+name); 55 | Product p = (Product) c.newInstance; 56 | return p; 57 | } 58 | } 59 | ``` 60 | 61 | And then you can use it by `Product p = Factory.getP("ProductA")` and not have multiple specific factories for each product. 62 | 63 | ### Real Singletons 64 | As of Java 8 and according to our tests, you can no longer instantiate a new instance of a singleton (using Reflections: `Class.forName("com.s.SingletonInstance").newInstance();`). You will get this error: 65 | ```java 66 | Exception in thread "main" java.lang.IllegalAccessException: Class com.s.Main can not access a member of class com.s.SingletonInstance with modifiers "private" 67 | at sun.reflect.Reflection.ensureMemberAccess(Unknown Source) 68 | at java.lang.Class.newInstance(Unknown Source) 69 | at com.s.Main.main(Main.java:6) 70 | ``` 71 | 72 | [Index](readme.md) -------------------------------------------------------------------------------- /day5.md: -------------------------------------------------------------------------------- 1 | # Day 5 2 | 3 | 4 | 5 | [Index](readme.md) -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | These are my own notes to a week long Java 8 course (which also touches on JEE, Spring and design patterns). These notes are designed to provide a quick overview of major changes, new ideas or just simply cool stuff! It is not a comprehensive guide and certainly does not outline all changes introduced with Java 8. But for any seasoned developers, it should serve as a good refresher. 3 | 4 | _The Java 8 release is arguably the biggest update to the Java lang since ever._ 5 | 6 | Let me know if I missed anything important or any typos. 7 | 8 | ## Table of Contents 9 | 10 | - [Day 1](#day-1): [What's New in Java 8](#whats-new-in-java-8), [Interface Additions](#interface-addtions), [Functional Programming](#functional-programming), [New Stream API](#new-stream-api), [New Optional Type](#new-optional-type) 11 | - [Day 2](day2.md): [New Collector Class](day2.md#new-collector-class), [Revamped Date/Time API](day2.md#revamped-datetime-api), [Reflections Design Pattern using Proxy Class](day2.md#reflections-design-pattern-using-proxy-class), [Write Javascript With Java](day2.md#write-javascript-with-java), [CDI: Java Standard for Dependency Injection & Interception](day2.md#cdi-java-standard-for-dependency-injection-interception), [Other New Features](day2.md#other-new-features) 12 | - [Day 3](day3.md): [CDI Cont'd: Using Qualifiers](day3.md#cdi-contd-using-qualifiers), [Dealing With Data](day3.md#dealing-with-data), [Websockets](day3.md#websockets) 13 | - [Day 4](day4.md): [Asynchronous Servlets](day4.md#asynchronous-servlets), [Spring MVC and REST Support](day4.md#spring-mvc-and-rest-support), [GoF Patterns](day4.md#gof-patterns) 14 | 15 | # Day 1 16 | ## What's New in Java 8 17 | - StreamAPI most important part of Java 8, built-in support for mapreduce 18 | - Java almost as if transitioning from OO to scripting (think Python) middle-ground 19 | - Finally supports lambdas/closures (a block of code/fn that we can pass around as data) 20 | -- not new, we used to do it with eventhandlers, now though we simplified the syntax. Some may call it syntactic sugar. 21 | -- and no longer need interface 22 | - Added foreach method for collections 23 | - Redesigned underlying multithreading code 24 | - Improved Javascript scripting engine (for Java app extensibility) 25 | - Default and static methods in interfaces 26 | - Replaced the DateTime API 27 | 28 | 29 | Note: JRE 8 is fully backward compatible with bytecode of previous Java versions. 30 | 31 | ## Interface Additions 32 | Can now have static methods in interfaces to provide utility methods. 33 | 34 | ```java 35 | public interface AgendaItem { 36 | static Comparator getDateTimeComparator() { 37 | return new Comparator() { 38 | 39 | @Override 40 | public int compare(AgendaItem o1, AgendaItem o2) { 41 | if (o1 == null) 42 | return -1; 43 | if (o2 == null) 44 | return 1; 45 | return o1.getDateTime().compareTo(o2.getDateTime()); 46 | } 47 | }; 48 | } 49 | } 50 | ``` 51 | 52 | Can now have default methods to leave existing implementations unchanged as you eventually end up changing your interface. 53 | ```java 54 | public interface DescriptionItem { 55 | default String getDescription() { 56 | return "descriptionItem: "+toString(); 57 | } 58 | } 59 | ``` 60 | 61 | ## Functional Programming 62 | Lambda API, 3 interfaces: 63 | - Consumer (takes 1 param and returns a void) 64 | - Function (takes 1 param and returns a value) 65 | - BiFunction (takes 2 params and returns a value) 66 | 67 | All these interfaces must only have one abstract method (this is what gets implemented as the lambda) aka Single Abstract Method interfaces. All interfaces that are like this are also called functional interfaces and can be used for lambdas. 68 | 69 | Examples: 70 | `list.forEach(myStr -> System.out.println(myStr))` 71 | _You can also wrap the println fn into a lambda:_ 72 | `list.forEach(System.out::println)` 73 | 74 | Starting a new thread now takes one line... 75 | `(new Thread(() -> {System.out.println(Thread.currentThread().getName)} )).start()` 76 | 77 | Type inference has been improved (e is an ActionEvent that I need not declare) 78 | `button.addActionListener(e -> System.out.println("Button Clicked!"))` 79 | 80 | An example of a BiFunction 81 | `Comparator c = (AgendaItem a1, AgendaItem a2) -> a1.getDateTime().compareTo(a2.getDateTime())` 82 | 83 | We can access non final variables in lambda that are from the enclosing scope. It will be treated as final, and you can't assign a value to it (even from outside the lambda) 84 | 85 | In a lambda expression, __this__, references the enclosing class, rather than the inner class. 86 | 87 | 88 | ## New Stream API 89 | 90 | Declarative programming, describe what the app should do- instead of how it should do it. 91 | Ie. compare your SQL statement with any nontrivial collection getter Java function. 92 | 93 | The Java Stream API allows for a declarative programming approach. 94 | ```java 95 | public List getDVDsByStudio(String studio) { 96 | Stream dvds = DVDDao.getAllDVDs().filter(s -> studio.equals(s.getStudio())); 97 | return dvds.collect(Collectors.toList()); 98 | } 99 | 100 | public List getGenres() { 101 | Stream dvds = DVDDao.getAllDVDs().map(DVD::getGenre).distinct().sorted(); 102 | return dvds.collect(Collectors.toList()); 103 | } 104 | ``` 105 | Very similar to Hibernate framework. 106 | 107 | Standard collections framework is not thread-safe. Streams allow us to manipulate collections of data in a thread-safe way. It handles synchronization on retrieval and on terminal stream. Intermediary steps should NOT modify the collection (if you were to roll your own). It also is far more efficient than say an Iterator since it doesn't take the whole collection in memory. 108 | 109 | ##New Optional Type 110 | Optional acts as a container for objects or it could be null. It is used instead of returning null. `optional.isPresent()` to check if an object exists. 111 | 112 | Helps address `NullPointerExceptions`. Seems like a solution looking for a problem. 113 | 114 | However, by declaring your methods to return an `Optional`, it serves as a reminder that the method __may__ return a null (thus use it judiciously). 115 | 116 | [Go to Day 2 >>](/day2.md) 117 | --------------------------------------------------------------------------------