INTRODUZIONE DEPENDENCY INJECTION E MVC: SPRING E ANGULARJS Un po’ di storia … Java beans EJB 1.0 EJB 3.0 • Riusabilità e composizionalità • Troppo semplici Transazionalità? Sicurezza? • Aggiunge ai beans componenti server-side • Servizi accedibili da remoto • Tecnologia molto complessa • Implementazione semplificata • Deployment semplificato (annotazioni) INGEGNERIA DEL SOFTWARE 1996 1998 2006 Università degli Studi di Padova Dipartimento di Matematica Corso di Laurea in Informatica, A.A. 2013 – 2014 2 [email protected] INTRODUZIONE “Spring is a lightweight inversion of control and aspect oriented container framework” Non è limitato alla componente server Utilizza componenti semplici (bean) Spring Permette di ridurre l’accoppiamento Ingegneria del software mod. B 3 Riccardo Cardin Non è intrusivo, gli oggetti sviluppati non dipendono da classi del framework Framework/Container Lightweight Framework opensource creato per ridurre la complessità dello sviluppo di applicazioni enterprise Riccardo Cardin INTRODUZIONE Spring Ingegneria del software mod. B Gestisce il ciclo di vita e la configurazione degli oggetti dell’applicazione. La configurazione utilizza XML o annotazioni. Lo sviluppatore può concentrarsi sulla logica di business IoC e DI Il container si fa carico di “iniettare” le dipendenze degli oggetti a runtime Ingegneria del software mod. B 4 Riccardo Cardin SPRING: CONCETTI SPRING: CONCETTI Plan Old Java Object (POJO) "We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it's caught on very nicely." Inversion of Control (principio di Hollywood) Il ciclo di vita degli oggetti è gestito da una entità esterna (container) Dependency Injection pattern Separa il comportamento di una componente dalla risoluzione delle sue dipendenze Minimizza il livello di accoppiamento La componente dichiara unicamente le sue dipendenze Un framework DI risolve a runtime le dipendenze dichiarate Dependency Injection Le dipendenze di un oggetto vengono “iniettate” nell’istanza automaticamente e a runtime Utilizzo costruttori e metodi setter 5 Ingegneria del software mod. B Riccardo Cardin DEPENDENCY INJECTION Utilizzo costruttori e metodi setter dei POJO Perdita dell’incapsulamento Ingegneria del software mod. B 6 Riccardo Cardin DEPENDENCY INJECTION Poor initialization Classic inizialization Utilizzo del design pattern factory … migliorando un po’ … 7 Ingegneria del software mod. B Riccardo Cardin 8 Ingegneria del software mod. B Riccardo Cardin DEPENDENCY INJECTION SPRING: ARCHITETTURA Spring injection ...e si vuole cambiare l’implementazione di B... Ingegneria del software mod. B 9 Riccardo Cardin SPRING: ARCHITETTURA org.springframework.beans.factory.BeanFactory Wiring bean Modulo JDBC e DAO Gestione degli accessi al datasource Evita la gestione delle connessioni Modulo MVC Implementazione del pattern factory, costruisce e risolve le dipendenze org.springframework.context.ApplicationContext Fornisce servizi come i18n, JNDI, EJB integration Riccardo Cardin Configurazione XML Application context Ingegneria del software mod. B Implementa l’IoC attraverso la BeanFactory 10 SPRING: COMPONENTI Core container Architettura del framework Costruzione e risoluzione delle dipendenze Costruita sulla bean factory, fornisce ulteriori funzionalità AOP, transazionalità, ... ApplicationContext ctx = new ClassPathXmlApplicationContext( "com/springinaction/springidol/filename.xml"); […] 11 MyBean bean = (MyBean) ctx.getBean(“beanid”); 12 Separa la logica di controllo da quella di business Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B Riccardo Cardin SPRING: COMPONENTI SPRING: COMPONENTI Configurazione XML Dependency injection attraverso proprietà Utilizzo metodi setter e getter <constructor-arg value="15"/> <constructor-arg ref="B"/> </bean > <property name="nome1" ref="B"/> <property name="nome2" value="una stringa"/> <property name="nome3" value="37"/> </bean > <bean id="B" class="nomeClasseB" /> </beans> <bean id="B" class="nomeClasseB" /> </beans> 13 Riccardo Cardin SPRING: COMPONENTI DI attraverso factory methods, init e destroy methods... Ingegneria del software mod. B 14 Riccardo Cardin SPRING: COMPONENTI Wiring utilizzando annotazioni Permette una gestione migliore della configurazione in progetti grandi Introduce una dipendenza da framework esterni Wiring utilizzando annotazioni @Inject/@Autowired Ricerca per tipo il bean della proprietà Si utilizza su costruttori, proprietà, ... Il bean non deve essere ambiguo Disambiguazione tramite @Named per l’ID @Autowired @Inject, annotazione JSR-330 @Resource, annotazione JSR-250 @Inject private Instrument instrument; <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> </beans> <context:annotation-config/> <context:component-scan base-package="org.example"/> [...] Ingegneria del software mod. B Dependency injection attraverso costruttori <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> </beans> <bean id="A" class="nomeClasseA" > <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> </beans> <bean id="A" class="nomeClasseA" > Ingegneria del software mod. B Configurazione XML @Inject @Named("guitar") private Instrument instrument2; 15 Riccardo Cardin Autodiscovery @Component, @Controller, @Service, ... Ingegneria del software mod. B 16 Riccardo Cardin SPRING SPRING: MVC Esempio Componente per lo sviluppo di applicazione web Interfacce e dependency injection Model View Ingegneria del software mod. B Riccardo Cardin FRONT CONTROLLER PATTERN Layer di visualizzazione/presentazione dati Utilizza la tecnologia JSP e Tag library Control 17 Layer della logica di business del sistema Layer che gestisce/controlla flussi e comunicazioni Dispatcher delle richieste (Front controller) Controller che implementano la logica applicativa Integrazione con Spring IoC container Utilizzo del DI pattern Ingegneria del software mod. B Riccardo Cardin FRONT CONTROLLER PATTERN Architettura Il controller è l’unico punto di accesso Gestisce le richieste in tutti gli aspetti 19 Ingegneria del software mod. B 18 Riccardo Cardin 20 Ingegneria del software mod. B Riccardo Cardin SPRING: MVC SPRING: MVC Architettura e componenti org.springframework.web.servlet.DispatcherServlet Front controller del framework Spring Da configurare nel file web.xml <servlet> <servlet-name>disp</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> Default servlet, non <servlet-mapping> preclude alcun formato <servlet-name>disp</servlet-name> nella risposta, ma gestisce <url-pattern>/</url-pattern> </servlet-mapping> anche i contenuti statici. 21 Ingegneria del software mod. B Riccardo Cardin SPRING: MVC 22 Riccardo Cardin Controller e annotazioni Racchiudono la logica dell’applicazione web DefaultAnnotationHandlerMapping http://localhost:8080/ExampleSpring/list Employee.htm <bean id ="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <value> /ex/view*.htm=helpController /**/help.htm=helpController </value> </property> </bean> Ingegneria del software mod. B <servlet-name>-servlet.xml Ingegneria del software mod. B <beans> <bean id="beanNameUrlMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <bean name="/listEmployee.htm" class="controllers.ListEmployeeController"> …. </bean> SimpleUrlHandlerMapping SPRING: MVC Handler mappings Associa la servlet (gli URL) con i controller BeanNameUrlHandlerMapping Configurata via XML (Web Application Context) 23 Riccardo Cardin Mapping delle richieste utilizzando @RequestMapping Sfrutta l’autowiring e l’autodiscovering dei bean POJO, più semplice da verificare (i.e. Mockito) <beans> <bean id="defaultHandlerMapping" class="org.springframework.web.portlet.mvc.annotation. DefaultAnnotationHandlerMapping" /> <mvc:annotation-driven/> <context:component-scanbasepackage="com.habuma.spitter.mvc"/> [...] </bean> Ingegneria del software mod. B 24 Riccardo Cardin SPRING: MVC SPRING: MVC Controller e annotazioni @Controller public ClassHomeController { Dichiarazione del Controller @RequestParam private SpitterService spitterService; Injection dell’applicazion logic @Inject public HomeController(SpitterServicespitterService) { this.spitterService = spitterService; } Spitterspitter=spitterService.getSpitter(username); model.addAttribute(spitter); model.addAttribute( spitterService.getSpittlesForSpitter(username)); return"spittles/list"; Dichiarazione URL gestiti @RequestMapping({"/","/home"}) public String showHomePage(Map<String,Object> model) { } model.put("spittles",spitterService.getRecentSpittles( DEFAULT_SPITTLES_PER_PAGE)); return "home"; Modello ritornato alla Mappa di stringhe – oggetti Convention over configuration (CoC) Da utilizzare con Controller annotati 25 Scelta della prossima view Ingegneria del software mod. B Riccardo Cardin SPRING: MVC Scelte da un risolutore (resolver) secondo il ModelAndView XmlViewResolver Usa un file di configurazione xml per la risoluzione delle view InternalResourceViewResolver <bean class="org.springframework.web.servlet.view.XmlViewResolver"> <property name="location"> <value>/WEB-INF/spring-views.xml</value> </property> </bean> UrlBasedViewResolver Esegue una risoluzione diretta del Ingegneria del software mod. B Componente view XmlViewResolver ResourceBundleViewResolver Usa un resource bundle (una serie di file con estensione .properties) per risolvere le view InternalResourceViewResolver Il nome logico viene utilizzato direttamente come nome della view. Riccardo Cardin [...] <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> [...] nome simbolico della view in una URL Ingegneria del software mod. B 26 SPRING: MVC Componente view org.springframework.ui.Model view } } Permette il recupero dei parametri da una richiesta @RequestMapping(value="/spittles",method=GET) public String listSpittlesForSpitter( @RequestParam("spitter") String username, Model model) { 27 Riccardo Cardin <beans xmlns=“…”> <bean id="WelcomePage“ class="org.springframework.web.servlet.view.JstlView"> <property name="url" value="/WEB-INF/pages/WelcomePage.jsp" /> </bean> </beans> Ingegneria del software mod. B 28 Riccardo Cardin SPRING: PERSISTENZA TEMPLATE METHOD Fornisce supporto uniforme verso lo strato di persistenza Definisce le operazione astratte primitive. Definisce lo scheletro dell’algoritmo JDBC, ORM, … Versione particolare del template method pattern Nessun metodo astratto Le firme dei metodi hanno come parametri interfacce che vengono risolte a runtime PreparedStatementCreator CallableStatementCreator RowCallbackHandler RowMapper ... Ingegneria del software mod. B Riccardo Cardin org.springframework.jdbc.core.JdbcTemplate public class JdbcCorporateEventDao implements CorporateEventDao { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } Ingegneria del software mod. B Accesso al JDBC layer in I/O Recupero primitivo int countOfActorsNamedJoe = this.jdbcTemplate.queryForInt("select count(0) from t_actors where first_name = ?", new Object[]{"Joe"}); Permette di costruire DAO utilizzando IoC } Riccardo Cardin Supporto JDBC Gestione trasparente delle connessioni Incapsulamento API JDBC (query, ResultSet, … ) Cattura le eccezioni JDBC e le trasforma in eccezioni più comunicative Ingegneria del software mod. B 30 SPRING: PERSISTENZA Supporto JDBC Implementa le operazioni primitive fornendo i passi concreti all’algoritmo 29 SPRING: PERSISTENZA Struttura 31 Riccardo Cardin Recupero oggetti public class ActorRowMapper implements RowMapper { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setFirstName(rs.getString("first_name")); actor.setSurname(rs.getString("surname")); return actor; } ... Actor actor = (Actor) this.jdbcTemplate.queryForObject( "select first_name, surname from t_actor where id = ?", new Object[]{new Long(1212)}, new ActorRowMapper() ); Ingegneria del software mod. B 32 Riccardo Cardin STRUMENTI ORM SPRING: PERSISTENZA Definizione Framework in grado di mappare proprietà di un oggetto con colonne di un DB ID: NUMBER Offrono specifici linguaggi di interrogazione Garantiscono sofisticate funzionalità FIRST_NAME: VARCHAR Lazy loading Eager fetching Caching Cascading … LAST_NAME: VARCHAR … JPA, Java Persistence API Ingegneria del software mod. B Riccardo Cardin Riccardo Cardin Hibernate org.springframework.orm.hibernate3.HibernateTemplate Fornisce l'accesso alla sessione di H8 Assicura che la session stessa sia appropriatamente aperta e chiusa Fornisce le funzionalità standard di accesso ai dati Necessità di datasource … inietiamolo con Spring! <beans> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="org.gjt.mm.mysql.Driver"/> </bean> <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="myDataSource"/> <property name="mappingResources"> <list> <value>hibernate.hbm.xml</value> </list> </property> ... </beans> Ingegneria del software mod. B Ingegneria del software mod. B H8 Session Factory è il gestore delle connessioni fra oggetti Java e il database 34 SPRING: PERSISTENZA Hibernate H8 public class Studente { private Integer id; private String firstName; private String lastName; private Set courses; ... public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } ... 33 SPRING: PERSISTENZA Mappa una tabella su un oggetto Studenti Persistenza garantita attraverso gli oggetti Hibernate public Collection loadAziende(final String category) throws DataAccessException { HibernateTemplate ht = new HibernateTemplate(this.sessionFactory); return (Collection) ht.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query query = session.createQuery("from spring-samples.Aziende aziende"); return query.list(); } }); } 35 Riccardo Cardin L’implementazione dell’interfaccia HibernateCallback permette l’interfacciamento Spring – H8 Ingegneria del software mod. B 36 Riccardo Cardin SPRING: PERSISTENZA Hibernate È possibile configurare HibernateTemplate direttamente con una session factory Non occorre più implementare HiberateCallback <bean id="hibernateTemplate“ class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean> public void updateStudent(Student student) { hibernateTemplate.update(student); } public List findStudentsByLastName(String lastName) { return hibernateTemplate.find("from Student student " + "where student.lastName = ?", lastName); } Ingegneria del software mod. B 37 Riccardo Cardin ANGULARJS … ma non c’è più tempo!!! 38 Ingegneria del software mod. B Client-side Riccardo Cardin «whatever works for you» Model – View – Whatever controller - modelview view model Model-View-Whatever Gestione delle transazioni Aspect Oriented Programming (AOP) Remoting Spring Roo Spring Social Spring Web Service Spring.io ... ANGULARJS Javascript framework Ci sarebbero ancora molti aspetti da trattare … MVC per alcuni aspetti (controller)… …MVVM per altri (two-way data binding) Templates Utilizza HTML come linguaggio di templating Views Non richiede operazioni di DOM refresh Controlla attivamente le azioni utente, eventi del browser Dependence injection Fornisce ottimi strumenti di test Ingegneria del software mod. B 39 Riccardo Cardin Realizza le viste utilizzando le proiezioni del modello Ingegneria del software mod. B $scope (ModelView) SPRING Services Controllers Espone i metodi dell’application logic e realizza il two-way data binding Model Modello dati e servizi di business logic 40 Riccardo Cardin ANGULARJS ANGULARJS Viste e templating Approccio dichiarativo: HTML Direttive Widget, aumentano le caratteristiche del DOM Il merge tra modello e template avviene all’atto di creazione della vista Effettua il binding agli elementi del view-model Solitamente contenuta in una sola pagina Riduce il dialogo con il server e non richiede refresh Le direttive <html ng-app> vengono compilate <body ng-controller="MyController"> <input ng-model="foo" value="bar"> <button ng-click="changeFoo()">{{buttonText}}</button> <script src="angular.js"> </body> </html> index.html Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B …the Angular way! Riccardo Cardin Oggetto $scope Collante tra controller e le viste Contesto di esecuzione per espressioni Il template è compilato in una live view La vista è una proiezione del modello (Model-View ViewModel) 43 Ingegneria del software mod. B 42 ANGULARJS Two-way data binding Modifiche al modello richiedono un aggiornamento esplicito e custom della vista 41 ANGULARJS …not the right way… Markup {{ }} One-way data binding Riccardo Cardin Alcune direttive creano uno scope $rootScope Gerarchia simile a quella definita dal DOM Browser event loop $watch: permette alle direttive di comprendere quando il view-model cambia $apply: permette alle direttive di modificare il view-model eseguendo funzioni Ingegneria del software mod. B 44 Riccardo Cardin ANGULARJS ANGULARJS Browser event loop Controller ng-controller Inizializza e aggiunge funzioni all’oggetto $scope var myApp = angular.module('spicyApp2', []); myApp.controller('SpicyCtrl', ['$scope', function($scope){ $scope.customSpice = "wasabi"; $scope.spice = 'very'; Aggiunta variabili e // Functions funzioni al view$scope.spicy = function(spice){ $scope.spice = spice; model }; view }]); <div ng-app="spicyApp2" ng-controller="SpicyCtrl"> <input ng-model="customSpice"> <button ng-click="spicy('chili')">Chili</button> <button ng-click="spicy(customSpice)">Custom spice</button> 46 <p>The food is {{spice}} spicy!</p> </div> 45 Ingegneria del software mod. B Ingegneria del software mod. B Riccardo Cardin ANGULARJS ANGULARJS Controller Contiene l’application logic di una singola vista Per questo si usano i servizi: $http, $resource, ... Dependence injection Non deve effettuare manipolizazione del DOM Non deve occuparsi dell’input formatting Non è un presenter! Usare i form controls Non deve occuparsi dell’output filtering Usare i filters Ingegneria del software mod. B Racchiudono la business logic Non contiene business logic Servizi Non ha riferimenti diretti alla vista Facilita la fasee di testing private 47 Riccardo Cardin public Riccardo Cardin Richiamati dai Controller angular.module('finance2', []) .factory('currencyConverter', function() { var currencies = ['USD', 'EUR', 'CNY'], usdToForeignRates = { USD: 1, EUR: 0.74, CNY: 6.09 }; function convert(amount, inCurr, outCurr) { return amount * usdToForeignRates[outCurr] * 1 / usdToForeignRates[inCurr]; } return { currencies: currencies, convert: convert }; }); Ingegneria del software mod. B 48 Riccardo Cardin ANGULARJS ANGULARJS Angular services Forniscono utilità comuni alle applicazioni $http Dependency Injection Permette di comunicare con servizi HTTP XMLHttpRequest o JSONP Utilizza Promises ($q) reactive programming promise Ingegneria del software mod. B Riccardo Cardin Ingegneria del software mod. B 50 Riccardo Cardin ANGULARJS Dependency Injection Dependency Injection Factory methods: costruiscono le componenti 51 Ingegneria del software mod. B Ritorna il servizio $provide // Teach the injector how to build a 'greeter' // Notice that greeter itself is dependent on '$window' factory('greeter', function($window) { // This is a factory function, and is responsible for // creating the 'greet' service. return { greet: function(text) { "Ricetta" di come $window.alert(text); costruire greeter } }; }); // Request any dependency from the $injector angular.injector(['myModule', 'ng']).get('greeter'); 49 ANGULARJS Viene invocato direttamente da Angular al bootstrap // Provide the wiring information in a module angular.module('myModule', []). $http({method: 'GET', url: '/someUrl'}). success(function(data, status, headers, config) { // this callback will be called asynchronously // when the response is available }). error(function(data, status, headers, config) { // called asynchronously if an error occurs // or server returns response with an error status. }); Gestione history ($location), logging ($log), ... $provide: risolve le dipendenze fra le componenti Riccardo Cardin Utilizzano recipe (ricette) angular.module('myModule', []). config(['depProvider', function(depProvider){ //... }]). factory('serviceId', ['depService', function(depService) { //... }]). directive('directiveName', ['depService', function(depService) { //... }]). filter('filterName', ['depService', function(depService) { //... }]). run(['depService', function(depService) { //... }]); Ingegneria del software mod. B 52 Riccardo Cardin RIFERIMENTI Spring Source, pagina ufficiale del progetto http://www.springsource.org/ Spring in Action (3° edition), Manning Publications Spring tutorial http://www.roseindia.net/spring/index.shtml Mastering Web Application Development with AngularJS, Packt Publishing AngularJS databing http://docs.angularjs.org/guide/databinding AngularJS controller http://docs.angularjs.org/guide/controller Inversion of Control Containers and the Dependency Injection pattern http://martinfowler.com/articles/injection.html Ingegneria del software mod. B 53 Riccardo Cardin
© Copyright 2024 Paperzz