Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 29

Anotacije

Anotacije
Meta podaci koji se na nivou izvornog
koda dodeljuju:
paketima , klasama,
metodama, atributima, parametrima metoda,
konstruktorima i
lokalnim varijablama.
JavaDoc, XDoclet

2/29
Anotacije
Ovako dodeljeni meta podaci se mogu
kasnije prepoznati i koristiti u toku
izvrenja programa (run-time) ili tokom
prevoenja.
Sa stanovita sintakse, anotacija se
dodaje kao:
@MojaAnotacija

3/29
Anotacija je interfejs
Specijalan interfejs:

public @interface ClassInfo {


String author();
String version();
}

4/29
Dodela anotacije
@ClassInfo(
author = "Milan Vidakovic",
version = "1.0"
)
public class AnnotationDemo {
...
}

5/29
Anotacija sa jednim elementom
Primer:
public @interface AttributeInfo {
String value();
}
Anotacija tipa AttributeInfo ima samo jedan
element i njegov podrazumevan naziv je value.
@AttributeInfo("Izbaciti u sledecoj
verziji")
int att = 1;

6/29
Anotacije bez elemenata
Primer:
public @interface Test {}
...
@Test public void f() { ... }

7/29
Meta-anotacije
Anotacije o anotacijama
Sistemske meta-anotacije:
@Retention nivo ukljuenja anotacije u
program
@Target emu se pridruuje anotacija
@Documented da li e pridruena anotacija
biti dokumentovana JavaDoc alatom ili nekim
drugim

8/29
@Retention

Tri vrste:
@Retention(RetentionPolicy.SOURCE)
anotacije se ne ugrauju u class datoteke
@Retention(RetentionPolicy.CLASS)
anotacije se ugrauju u class datoteke, ali se ne
mogu proitati refleksijom
@Retention(RetentionPolicy.RUNTIME)
anotacije se ugrauju u class datoteke i mogu se
proitati refleksijom

9/29
@Target

Osam varijanti:
@Target(ElementType.ANNOTATION_TYPE)
za definiciju meta-anotacije
@Target(ElementType.CONSTRUCTOR)
anotacija se moe dodeliti samo konstruktorima
@Target(ElementType.FIELD)
anotacija se moe dodeliti samo atributima
@Target(ElementType.LOCAL_VARIABLE)
anotacija se moe dodeliti samo lokalnim promenljivama

10/29
@Target
Nastavak:
@Target(ElementType.METHOD)
anotacija se moe dodeliti samo metodama
@Target(ElementType.PACKAGE)
anotacija se moe dodeliti samo deklaraciji paketa
@Target(ElementType.PARAMETER)
anotacija se moe dodeliti samo parametrima metoda
@Target(ElementType.TYPE)
anotacija se moe dodeliti samo definiciji klase, interfejsa,
enumeracije ili anotacije

11/29
Anotacije i refleksija
Prilikom definicije anotacije, mora se
navesti @Retention meta-anotacija:
@Retention(RetentionPolicy.RUNTIME)
Poeljno je i precizirati za koji entitet se
vezuje anotacija - @Target anotacija
Koristi se metoda getAnnotation(Class
annotationInterface) klasa Class, Method i
Field.

12/29
AnnotationProcessing Tool

Ime programa je apt


Pronalazi i izvrava procesore anotacija
(annotation procesors) na osnovu pronaenih
anotacija u izvornom kodu.
Procesori anotacija
specifine klase napisane da procesiraju zadate tipove
anotacija
mogu da generiu nove izvorne datoteke i druge tipove
datoteka
mogu da izazovu kompajliranje novonastalih izvornih
datoteka.
13/29
java.lang anotacije
@Depricated
zastareo kod
izaziva warning
@Override
ako stavimo ovu anotaciju iznad metode koja
redefine odgovarajuu metodu, kompajler e
proveriti da li se ime slae

@SuppressWarnings({"unchecked",
"depricated"})
iskljuuje upozorenja zadatog tipa

14/29
java.lang.annotation anotacije
@Documented
da li da se ukljui u javadoc dokumentaciju
@Inherited
anotacija se trai u roditeljskoj klasi ako ne postoji u
klasi naslednici
@Retention
nivo ukljuenja anotacije
@Target
kome se dodeljuje anotacija

15/29
Upotreba
EJB
Web servisi
ostalo

16/29
EJB Session Bean

@Stateless
public class HelloBean implements HelloRemote
{

public String hello() {


String str = "Hello World!";
System.out.println(str);
return str;
}
}

17/29
EJB Remote interfejs
Anotacijom @Remote definie se Remote
interfejs

import javax.ejb.Remote;
@Remote
public interface Hello {
public String hello();
}

18/29
EJB Local interfejs
Anotacijom @Local definie se Local interfejs

import javax.ejb.Local;
@Local
public interface DrugiLocal {
public long f();
}

19/29
EJB Entity
@Entity
public class Book implements Serializable {
private Integer id;
private String title;
public Book(Integer id, String title) {
this.id = id;
this.title = title;
}
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
20/29
}
Web Service bean

@Stateless
@WebService(
endpointInterface = "web_service.EchoSEI",
serviceName = "EchoServis",
targetNamespace="http://web_servis_ns")
@Remote(EchoSEI.class)
public class EchoBean {
public String echo(String in) throws RemoteException
{
return "WS response: " + in;
}
}

21/29
Web Service SEI
@WebService(
name = "EchoProxy",
targetNamespace="http://web_servis_ns")
@SOAPBinding(
style = Style.RPC,
parameterStyle=ParameterStyle.WRAPPED,
use=Use.LITERAL)
@Remote
public interface EchoSEI {
@WebMethod
String echo(String in) throws RemoteException;
}

22/29
Ostalo
Primer "nove" upotrebe Swing oslukivaa
Umesto prijavljivanja oslukivaa, napie
se anotacija iznad metode
Koristi se klasa Proxy i InvocationHandler
interfejs

23/29
Klasa Proxy
Kreira dinamiku proxy klasu i njene instance
Instancira se navoenjem class loader-a, liste
interfejsa koje implementira i reference na
objekat koji implementira InvocationHandler
intefejs
InvocationHandler interfejs ima metodu invoke
koja se poziva kada se pozove bilo koja metoda
proxy klase

24/29
Klasa Proxy
Motivacija: imamo interfejs koji se mora
run-time implementirati
Realizacija: kreira se objekat klase Proxy,
koji se moe kastovati u pogodan interfejs
(koji implementira)

25/29
Primer
class ButtonFrame extends JFrame {
public ButtonFrame() {
setTitle("ButtonTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
panel = new JPanel();
add(panel);
blueButton = new JButton("Blue");
redButton = new JButton("Red");
panel.add(blueButton);
panel.add(redButton);

ActionListenerInstaller.processAnnotations(this);
}

@ActionListenerFor(source="blueButton")
public void blueBackground() {
panel.setBackground(Color.BLUE);
}

@ActionListenerFor(source="redButton")
public void redBackground() {
panel.setBackground(Color.RED);
} 26/29
}
ActionListenerFor
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionListenerFor
{
String source();
}

27/29
ActionListenerInstaller
public static void processAnnotations(Object obj) {
try {
Class cl = obj.getClass();
for (Method m : cl.getDeclaredMethods()) {
ActionListenerFor a =
m.getAnnotation(ActionListenerFor.class);
if (a != null) {
Field f = cl.getDeclaredField(a.source());
f.setAccessible(true);
addListener(f.get(obj), obj, m);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

28/29
ActionListenerInstaller
public static void addListener(Object source, final Object frame,
final Method m) throws NoSuchMethodException,
IllegalAccessException, InvocationTargetException {
InvocationHandler handler = new InvocationHandler() {
public Object invoke(Object proxy, Method mm, Object[] args)
throws Throwable {
return m.invoke(frame);
}
};

Object listener = Proxy.newProxyInstance(null,


new Class[] { java.awt.event.ActionListener.class },
handler);
Method adder = source.getClass().getMethod("addActionListener",
ActionListener.class);
adder.invoke(source, listener);
}
29/29

You might also like